From 558d0c2a4f609d4e2b414addf468d0574006f3d4 Mon Sep 17 00:00:00 2001
From: Brett Porter
Date: Fri, 18 Apr 2008 03:05:18 +0000
Subject: [PATCH] [MRM-781] Removal of Archiva-Webdav implementation in favor
of Jackrabbit-webdav Submitted by: James William Dumay
git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@649352 13f79535-47bb-0310-9956-ffa450edef68
---
archiva-jetty/pom.xml | 2 +-
.../archiva/security}/ArchivaXworkUser.java | 26 +-
.../archiva-web/archiva-webapp/pom.xml | 10 -
.../archiva/web/action/BrowseAction.java | 10 +-
.../archiva/web/action/SearchAction.java | 10 +-
.../web/action/ShowArtifactAction.java | 5 +-
.../archiva/web/action/UploadAction.java | 5 +-
.../web/repository/ProxiedDavServer.java | 598 ---------
.../web/repository/RepositoryServlet.java | 266 ++--
.../resources/META-INF/plexus/application.xml | 17 +-
...aderTest.java => MimeTypesLoaderTest.java} | 5 +-
.../UnauthenticatedDavSessionProvider.java | 50 +
.../UnauthenticatedRepositoryServlet.java | 23 +-
.../archiva-web/archiva-webdav/pom.xml | 79 +-
.../main/java/it/could/util/StreamTools.java | 125 --
.../main/java/it/could/util/StringTools.java | 214 ----
.../it/could/util/encoding/Encodable.java | 48 -
.../it/could/util/encoding/EncodingAware.java | 37 -
.../it/could/util/encoding/EncodingTools.java | 274 -----
.../java/it/could/util/encoding/package.html | 61 -
.../java/it/could/util/http/HttpClient.java | 1070 -----------------
.../java/it/could/util/http/WebDavClient.java | 901 --------------
.../main/java/it/could/util/http/package.html | 12 -
.../java/it/could/util/location/Location.java | 805 -------------
.../it/could/util/location/Parameters.java | 474 --------
.../java/it/could/util/location/Path.java | 559 ---------
.../java/it/could/util/location/package.html | 29 -
.../src/main/java/it/could/util/package.html | 11 -
.../java/it/could/webdav/DAVException.java | 132 --
.../java/it/could/webdav/DAVInputStream.java | 165 ---
.../java/it/could/webdav/DAVListener.java | 46 -
.../main/java/it/could/webdav/DAVLogger.java | 86 --
.../main/java/it/could/webdav/DAVMethod.java | 41 -
.../java/it/could/webdav/DAVMultiStatus.java | 149 ---
.../java/it/could/webdav/DAVNotModified.java | 56 -
.../java/it/could/webdav/DAVOutputStream.java | 187 ---
.../java/it/could/webdav/DAVProcessor.java | 92 --
.../java/it/could/webdav/DAVRepository.java | 164 ---
.../java/it/could/webdav/DAVResource.java | 514 --------
.../main/java/it/could/webdav/DAVServlet.java | 280 -----
.../java/it/could/webdav/DAVTransaction.java | 280 -----
.../java/it/could/webdav/DAVUtilities.java | 420 -------
.../java/it/could/webdav/XMLRepository.java | 113 --
.../java/it/could/webdav/methods/COPY.java | 71 --
.../java/it/could/webdav/methods/DELETE.java | 54 -
.../java/it/could/webdav/methods/GET.java | 144 ---
.../java/it/could/webdav/methods/HEAD.java | 79 --
.../java/it/could/webdav/methods/MKCOL.java | 57 -
.../java/it/could/webdav/methods/MOVE.java | 80 --
.../java/it/could/webdav/methods/OPTIONS.java | 52 -
.../it/could/webdav/methods/PROPFIND.java | 122 --
.../it/could/webdav/methods/PROPPATCH.java | 55 -
.../java/it/could/webdav/methods/PUT.java | 72 --
.../java/it/could/webdav/methods/package.html | 12 -
.../main/java/it/could/webdav/package.html | 134 ---
.../could/webdav/replication/DAVReplica.java | 242 ----
.../webdav/replication/DAVReplicator.java | 131 --
.../it/could/webdav/replication/package.html | 12 -
.../webdav/AbstractDavServerComponent.java | 159 ---
.../webdav/ArchivaDavLocatorFactory.java | 72 ++
.../archiva/webdav/ArchivaDavResource.java | 301 +++++
.../webdav/ArchivaDavResourceFactory.java | 497 ++++++++
.../webdav/ArchivaDavResourceLocator.java | 136 +++
.../archiva/webdav/ArchivaDavSession.java | 53 +
.../webdav/ArchivaDavSessionProvider.java | 154 +++
.../archiva/webdav/DavServerComponent.java | 143 ---
.../archiva/webdav/DavServerListener.java | 39 -
.../archiva/webdav/DavServerManager.java | 74 --
.../webdav/DefaultDavServerManager.java | 88 --
...erverRequest.java => LogicalResource.java} | 29 +-
...ion.java => UnauthorizedDavException.java} | 36 +-
.../webdav/servlet/AbstractWebDavServlet.java | 164 ---
.../servlet/basic/BasicDavServerRequest.java | 67 --
.../servlet/basic/BasicWebDavServlet.java | 142 ---
.../MultiplexedDavServerRequest.java | 123 --
.../multiplexed/MultiplexedWebDavServlet.java | 137 ---
.../webdav/simple/HackedMoveMethod.java | 130 --
.../webdav/simple/ReplacementGetMethod.java | 303 -----
.../simple/SimpleDavServerComponent.java | 185 ---
.../archiva/webdav/util/IndexWriter.java | 111 ++
.../maven/archiva/webdav/util/MimeTypes.java | 20 +-
.../webdav/util/RepositoryPathUtil.java | 105 ++
.../archiva/webdav/util/WebdavMethodUtil.java | 6 +-
.../webdav/util/WrappedRepositoryRequest.java | 184 ---
.../org/betaversion/webdav/DAVServlet.java | 57 -
.../java/org/betaversion/webdav/package.html | 15 -
.../maven/archiva/webdav/util/mime-types.txt | 128 --
.../maven/archiva/webdav/util}/mime.types | 8 +-
.../main/resources/plexus-webdav/webdav.props | 13 -
.../webdav/TestableHttpServletRequest.java | 495 --------
.../MultiplexedDavServerRequestTest.java | 67 --
.../SimpleDavServerComponentBasicTest.java | 38 -
...SimpleDavServerComponentIndexHtmlTest.java | 38 -
.../SimpleDavServerComponentMultiTest.java | 38 -
.../webdav/simple/SimpleWebdavServer.java | 50 -
.../AbstractBasicWebdavProviderTestCase.java | 255 ----
.../AbstractMultiWebdavProviderTestCase.java | 203 ----
.../test/AbstractWebdavIndexHtmlTestCase.java | 148 ---
.../test/AbstractWebdavProviderTestCase.java | 401 ------
.../webdav/test/AbstractWebdavServer.java | 163 ---
.../webdav/test/TestMultiWebDavServlet.java | 46 -
.../util/WrappedRepositoryRequestTest.java | 75 --
pom.xml | 5 +
103 files changed, 1747 insertions(+), 13722 deletions(-)
rename archiva-modules/archiva-web/{archiva-webapp/src/main/java/org/apache/maven/archiva/web/util => archiva-security/src/main/java/org/apache/maven/archiva/security}/ArchivaXworkUser.java (68%)
delete mode 100644 archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/ProxiedDavServer.java
rename archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/repository/{ArchivaMimeTypeLoaderTest.java => MimeTypesLoaderTest.java} (90%)
create mode 100644 archiva-modules/archiva-web/archiva-webapp/src/test/java/org/apache/maven/archiva/web/repository/UnauthenticatedDavSessionProvider.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/StreamTools.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/StringTools.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/encoding/Encodable.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/encoding/EncodingAware.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/encoding/EncodingTools.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/encoding/package.html
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/http/HttpClient.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/http/WebDavClient.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/http/package.html
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Location.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Parameters.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Path.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/location/package.html
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/package.html
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVException.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVInputStream.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVListener.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVLogger.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVMethod.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVMultiStatus.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVNotModified.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVOutputStream.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVProcessor.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVRepository.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVResource.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVServlet.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVTransaction.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVUtilities.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/XMLRepository.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/COPY.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/DELETE.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/GET.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/HEAD.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/MKCOL.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/MOVE.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/OPTIONS.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/PROPFIND.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/PROPPATCH.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/PUT.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/package.html
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/package.html
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/replication/DAVReplica.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/replication/DAVReplicator.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/replication/package.html
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/AbstractDavServerComponent.java
create mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavLocatorFactory.java
create mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResource.java
create mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java
create mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceLocator.java
create mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSession.java
create mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DavServerComponent.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DavServerListener.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DavServerManager.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DefaultDavServerManager.java
rename archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/{servlet/DavServerRequest.java => LogicalResource.java} (58%)
rename archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/{DavServerException.java => UnauthorizedDavException.java} (59%)
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/AbstractWebDavServlet.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/basic/BasicDavServerRequest.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/basic/BasicWebDavServlet.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/multiplexed/MultiplexedDavServerRequest.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/multiplexed/MultiplexedWebDavServlet.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/simple/HackedMoveMethod.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/simple/ReplacementGetMethod.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/simple/SimpleDavServerComponent.java
create mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/IndexWriter.java
create mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/RepositoryPathUtil.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/WrappedRepositoryRequest.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/betaversion/webdav/DAVServlet.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/java/org/betaversion/webdav/package.html
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/resources/org/apache/maven/archiva/webdav/util/mime-types.txt
rename archiva-modules/archiva-web/archiva-webdav/src/main/resources/{plexus-webdav => org/apache/maven/archiva/webdav/util}/mime.types (97%)
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/main/resources/plexus-webdav/webdav.props
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/TestableHttpServletRequest.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/servlet/multiplexed/MultiplexedDavServerRequestTest.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/simple/SimpleDavServerComponentBasicTest.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/simple/SimpleDavServerComponentIndexHtmlTest.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/simple/SimpleDavServerComponentMultiTest.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/simple/SimpleWebdavServer.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/AbstractBasicWebdavProviderTestCase.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/AbstractMultiWebdavProviderTestCase.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/AbstractWebdavIndexHtmlTestCase.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/AbstractWebdavProviderTestCase.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/AbstractWebdavServer.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/TestMultiWebDavServlet.java
delete mode 100644 archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/util/WrappedRepositoryRequestTest.java
diff --git a/archiva-jetty/pom.xml b/archiva-jetty/pom.xml
index 04220dc75..6dbe6c038 100644
--- a/archiva-jetty/pom.xml
+++ b/archiva-jetty/pom.xml
@@ -255,7 +255,7 @@
- codehaus.org
+ codehaus.snapshots
http://snapshots.repository.codehaus.org/
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/util/ArchivaXworkUser.java b/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaXworkUser.java
similarity index 68%
rename from archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/util/ArchivaXworkUser.java
rename to archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaXworkUser.java
index 208d82ebe..4189392e6 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/util/ArchivaXworkUser.java
+++ b/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaXworkUser.java
@@ -1,4 +1,4 @@
-package org.apache.maven.archiva.web.util;
+package org.apache.maven.archiva.security;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -27,8 +27,6 @@ import org.codehaus.plexus.redback.system.SecuritySession;
import org.codehaus.plexus.redback.system.SecuritySystemConstants;
import org.codehaus.plexus.redback.users.User;
-import com.opensymphony.xwork.ActionContext;
-
/**
* ArchivaXworkUser
*
@@ -37,35 +35,21 @@ import com.opensymphony.xwork.ActionContext;
*/
public class ArchivaXworkUser
{
- private static Map getContextSession()
+ public static String getActivePrincipal( Map sessionMap )
{
- ActionContext context = ActionContext.getContext();
- Map sessionMap = context.getSession();
if ( sessionMap == null )
{
- sessionMap = new HashMap();
+ return ArchivaRoleConstants.PRINCIPAL_GUEST;
}
- return sessionMap;
- }
-
- private static SecuritySession getSecuritySession()
- {
SecuritySession securitySession =
- (SecuritySession) getContextSession().get( SecuritySystemConstants.SECURITY_SESSION_KEY );
+ (SecuritySession) sessionMap.get( SecuritySystemConstants.SECURITY_SESSION_KEY );
if ( securitySession == null )
{
- securitySession = (SecuritySession) getContextSession().get( SecuritySession.ROLE );
+ securitySession = (SecuritySession) sessionMap.get( SecuritySession.ROLE );
}
- return securitySession;
- }
-
- public static String getActivePrincipal()
- {
- SecuritySession securitySession = getSecuritySession();
-
if ( securitySession == null )
{
return ArchivaRoleConstants.PRINCIPAL_GUEST;
diff --git a/archiva-modules/archiva-web/archiva-webapp/pom.xml b/archiva-modules/archiva-web/archiva-webapp/pom.xml
index b19f67052..a78b2139b 100644
--- a/archiva-modules/archiva-web/archiva-webapp/pom.xml
+++ b/archiva-modules/archiva-web/archiva-webapp/pom.xml
@@ -136,16 +136,6 @@
commons-lang
commons-lang
-
- org.apache.maven.wagon
- wagon-http
- runtime
-
-
- org.apache.maven.wagon
- wagon-file
- runtime
-
com.opensymphony
webwork
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/BrowseAction.java b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/BrowseAction.java
index 09ab2d3df..fc0f4757d 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/BrowseAction.java
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/BrowseAction.java
@@ -22,15 +22,13 @@ package org.apache.maven.archiva.web.action;
import java.util.Collections;
import java.util.List;
+import com.opensymphony.xwork.ActionContext;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.database.browsing.BrowsingResults;
import org.apache.maven.archiva.database.browsing.RepositoryBrowsing;
-import org.apache.maven.archiva.security.AccessDeniedException;
-import org.apache.maven.archiva.security.ArchivaSecurityException;
-import org.apache.maven.archiva.security.PrincipalNotFoundException;
-import org.apache.maven.archiva.security.UserRepositories;
-import org.apache.maven.archiva.web.util.ArchivaXworkUser;
+import org.apache.maven.archiva.security.*;
+import org.apache.maven.archiva.security.ArchivaXworkUser;
import org.codehaus.plexus.xwork.action.PlexusActionSupport;
/**
@@ -121,7 +119,7 @@ public class BrowseAction
private String getPrincipal()
{
- return ArchivaXworkUser.getActivePrincipal();
+ return ArchivaXworkUser.getActivePrincipal( ActionContext.getContext().getSession() );
}
private List getObservableRepos()
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/SearchAction.java b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/SearchAction.java
index fbce024a4..6e91a5799 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/SearchAction.java
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/SearchAction.java
@@ -23,6 +23,7 @@ import java.net.MalformedURLException;
import java.util.Collections;
import java.util.List;
+import com.opensymphony.xwork.ActionContext;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.database.ArchivaDAO;
@@ -33,11 +34,8 @@ import org.apache.maven.archiva.indexer.RepositoryIndexSearchException;
import org.apache.maven.archiva.indexer.search.CrossRepositorySearch;
import org.apache.maven.archiva.indexer.search.SearchResultLimits;
import org.apache.maven.archiva.indexer.search.SearchResults;
-import org.apache.maven.archiva.security.AccessDeniedException;
-import org.apache.maven.archiva.security.ArchivaSecurityException;
-import org.apache.maven.archiva.security.PrincipalNotFoundException;
-import org.apache.maven.archiva.security.UserRepositories;
-import org.apache.maven.archiva.web.util.ArchivaXworkUser;
+import org.apache.maven.archiva.security.*;
+import org.apache.maven.archiva.security.ArchivaXworkUser;
import org.codehaus.plexus.xwork.action.PlexusActionSupport;
/**
@@ -155,7 +153,7 @@ public class SearchAction
private String getPrincipal()
{
- return ArchivaXworkUser.getActivePrincipal();
+ return ArchivaXworkUser.getActivePrincipal( ActionContext.getContext().getSession() );
}
private List getObservableRepos()
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/ShowArtifactAction.java b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/ShowArtifactAction.java
index 8f5fab1be..286d32561 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/ShowArtifactAction.java
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/ShowArtifactAction.java
@@ -31,9 +31,10 @@ import org.apache.maven.archiva.security.AccessDeniedException;
import org.apache.maven.archiva.security.ArchivaSecurityException;
import org.apache.maven.archiva.security.PrincipalNotFoundException;
import org.apache.maven.archiva.security.UserRepositories;
-import org.apache.maven.archiva.web.util.ArchivaXworkUser;
+import org.apache.maven.archiva.security.ArchivaXworkUser;
import org.codehaus.plexus.xwork.action.PlexusActionSupport;
+import com.opensymphony.xwork.ActionContext;
import com.opensymphony.xwork.Validateable;
/**
@@ -173,7 +174,7 @@ public class ShowArtifactAction
private String getPrincipal()
{
- return ArchivaXworkUser.getActivePrincipal();
+ return ArchivaXworkUser.getActivePrincipal( ActionContext.getContext().getSession() );
}
private List getObservableRepos()
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/UploadAction.java b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/UploadAction.java
index fbaca57ae..e4e9b0b00 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/UploadAction.java
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/UploadAction.java
@@ -51,9 +51,10 @@ import org.apache.maven.archiva.repository.project.writers.ProjectModel400Writer
import org.apache.maven.archiva.security.ArchivaSecurityException;
import org.apache.maven.archiva.security.PrincipalNotFoundException;
import org.apache.maven.archiva.security.UserRepositories;
-import org.apache.maven.archiva.web.util.ArchivaXworkUser;
+import org.apache.maven.archiva.security.ArchivaXworkUser;
import org.codehaus.plexus.xwork.action.PlexusActionSupport;
+import com.opensymphony.xwork.ActionContext;
import com.opensymphony.xwork.Preparable;
import com.opensymphony.xwork.Validateable;
@@ -325,7 +326,7 @@ public class UploadAction
private String getPrincipal()
{
- return ArchivaXworkUser.getActivePrincipal();
+ return ArchivaXworkUser.getActivePrincipal( ActionContext.getContext().getSession() );
}
private void copyFile( File targetPath, String artifactFilename )
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/ProxiedDavServer.java b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/ProxiedDavServer.java
deleted file mode 100644
index 32168b7f5..000000000
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/ProxiedDavServer.java
+++ /dev/null
@@ -1,598 +0,0 @@
-package org.apache.maven.archiva.web.repository;
-
-/*
- * 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.
- */
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.maven.archiva.common.utils.PathUtil;
-import org.apache.maven.archiva.model.ArtifactReference;
-import org.apache.maven.archiva.model.ProjectReference;
-import org.apache.maven.archiva.model.VersionedReference;
-import org.apache.maven.archiva.policies.ProxyDownloadException;
-import org.apache.maven.archiva.proxy.RepositoryProxyConnectors;
-import org.apache.maven.archiva.repository.ManagedRepositoryContent;
-import org.apache.maven.archiva.repository.RepositoryContentFactory;
-import org.apache.maven.archiva.repository.RepositoryException;
-import org.apache.maven.archiva.repository.RepositoryNotFoundException;
-import org.apache.maven.archiva.repository.audit.AuditEvent;
-import org.apache.maven.archiva.repository.audit.AuditListener;
-import org.apache.maven.archiva.repository.audit.Auditable;
-import org.apache.maven.archiva.repository.content.RepositoryRequest;
-import org.apache.maven.archiva.repository.layout.LayoutException;
-import org.apache.maven.archiva.repository.metadata.MetadataTools;
-import org.apache.maven.archiva.repository.metadata.RepositoryMetadataException;
-import org.apache.maven.archiva.web.util.ArchivaXworkUser;
-import org.apache.maven.archiva.webdav.AbstractDavServerComponent;
-import org.apache.maven.archiva.webdav.DavServerComponent;
-import org.apache.maven.archiva.webdav.DavServerException;
-import org.apache.maven.archiva.webdav.DavServerListener;
-import org.apache.maven.archiva.webdav.servlet.DavServerRequest;
-import org.apache.maven.archiva.webdav.util.WebdavMethodUtil;
-import org.apache.maven.model.DistributionManagement;
-import org.apache.maven.model.Model;
-import org.apache.maven.model.Relocation;
-import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
-import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
-
-/**
- * ProxiedDavServer
- *
- * @author Joakim Erdfelt
- * @version $Id$
- * @plexus.component role="org.apache.maven.archiva.webdav.DavServerComponent"
- * role-hint="proxied" instantiation-strategy="per-lookup"
- */
-public class ProxiedDavServer
- extends AbstractDavServerComponent
- implements Auditable
-{
- /**
- * @plexus.requirement role-hint="simple"
- */
- private DavServerComponent davServer;
-
- /**
- * @plexus.requirement role="org.apache.maven.archiva.repository.audit.AuditListener"
- */
- private List auditListeners = new ArrayList();
-
- /**
- * @plexus.requirement
- */
- private RepositoryContentFactory repositoryFactory;
-
- /**
- * @plexus.requirement
- */
- private RepositoryRequest repositoryRequest;
-
- /**
- * @plexus.requirement role-hint="default"
- */
- private RepositoryProxyConnectors connectors;
-
- /**
- * @plexus.requirement
- */
- private MetadataTools metadataTools;
-
- private ManagedRepositoryContent managedRepository;
-
- public String getPrefix()
- {
- return davServer.getPrefix();
- }
-
- public File getRootDirectory()
- {
- return davServer.getRootDirectory();
- }
-
- public void setPrefix( String prefix )
- {
- davServer.setPrefix( prefix );
- }
-
- public void setRootDirectory( File rootDirectory )
- {
- davServer.setRootDirectory( rootDirectory );
- }
-
- public void init( ServletConfig servletConfig )
- throws DavServerException
- {
- davServer.init( servletConfig );
-
- try
- {
- managedRepository = repositoryFactory.getManagedRepositoryContent( getPrefix() );
- }
- catch ( RepositoryNotFoundException e )
- {
- throw new DavServerException( e.getMessage(), e );
- }
- catch ( RepositoryException e )
- {
- throw new DavServerException( e.getMessage(), e );
- }
- }
-
- public void process( DavServerRequest request, HttpServletResponse response )
- throws DavServerException, ServletException, IOException
- {
- boolean isGet = WebdavMethodUtil.isReadMethod( request.getRequest().getMethod() );
- boolean isPut = WebdavMethodUtil.isWriteMethod( request.getRequest().getMethod() );
- String resource = request.getLogicalResource();
-
- if ( isGet )
- {
- // Default behaviour is to treat the resource natively.
- File resourceFile = new File( managedRepository.getRepoRoot(), resource );
-
- // If this a directory resource, then we are likely browsing.
- if ( resourceFile.exists() && resourceFile.isDirectory() )
- {
- String requestURL = request.getRequest().getRequestURL().toString();
-
- // [MRM-440] - If webdav URL lacks a trailing /, navigating to
- // all links in the listing return 404.
- if ( !requestURL.endsWith( "/" ) )
- {
- String redirectToLocation = requestURL + "/";
- response.sendRedirect( redirectToLocation );
- return;
- }
-
- // Process the request.
- davServer.process( request, response );
-
- // All done.
- return;
- }
-
- // At this point the incoming request can either be in default or
- // legacy layout format.
- try
- {
- boolean fromProxy = fetchContentFromProxies( request, resource );
-
- // Perform an adjustment of the resource to the managed
- // repository expected path.
- resource =
- repositoryRequest
- .toNativePath( request.getLogicalResource(), managedRepository );
- resourceFile = new File( managedRepository.getRepoRoot(), resource );
-
- // Adjust the pathInfo resource to be in the format that the dav
- // server impl expects.
- request.setLogicalResource( resource );
-
- boolean previouslyExisted = resourceFile.exists();
-
- // Attempt to fetch the resource from any defined proxy.
- if ( fromProxy )
- {
- processAuditEvents( request, resource, previouslyExisted, resourceFile,
- " (proxied)" );
- }
- }
- catch ( LayoutException e )
- {
- // Invalid resource, pass it on.
- respondResourceMissing( request, response, e );
-
- // All done.
- return;
- }
-
- if ( resourceFile.exists() )
- {
- // [MRM-503] - Metadata file need Pragma:no-cache response
- // header.
- if ( request.getLogicalResource().endsWith( "/maven-metadata.xml" ) )
- {
- response.addHeader( "Pragma", "no-cache" );
- response.addHeader( "Cache-Control", "no-cache" );
- }
-
- // TODO: [MRM-524] determine http caching options for other
- // types of files (artifacts, sha1, md5, snapshots)
-
- davServer.process( request, response );
- }
- else
- {
- respondResourceMissing( request, response, null );
- }
- }
-
- if ( isPut )
- {
- /*
- * Create parent directories that don't exist when writing a file
- * This actually makes this implementation not compliant to the
- * WebDAV RFC - but we have enough knowledge about how the
- * collection is being used to do this reasonably and some versions
- * of Maven's WebDAV don't correctly create the collections
- * themselves.
- */
-
- File rootDirectory = getRootDirectory();
- if ( rootDirectory != null )
- {
- File destDir = new File( rootDirectory, resource ).getParentFile();
- if ( !destDir.exists() )
- {
- destDir.mkdirs();
- String relPath =
- PathUtil.getRelative( rootDirectory.getAbsolutePath(), destDir );
- triggerAuditEvent( request, relPath, AuditEvent.CREATE_DIR );
- }
- }
-
- File resourceFile = new File( managedRepository.getRepoRoot(), resource );
-
- boolean previouslyExisted = resourceFile.exists();
-
- // Allow the dav server to process the put request.
- davServer.process( request, response );
-
- processAuditEvents( request, resource, previouslyExisted, resourceFile, null );
-
- // All done.
- return;
- }
- }
-
- private void respondResourceMissing( DavServerRequest request, HttpServletResponse response,
- Throwable t )
- {
- response.setStatus( HttpServletResponse.SC_NOT_FOUND );
-
- try
- {
- StringBuffer missingUrl = new StringBuffer();
- missingUrl.append( request.getRequest().getScheme() ).append( "://" );
- missingUrl.append( request.getRequest().getServerName() ).append( ":" );
- missingUrl.append( request.getRequest().getServerPort() );
- missingUrl.append( request.getRequest().getServletPath() );
-
- String message = "Error 404 Not Found";
-
- PrintWriter out = new PrintWriter( response.getOutputStream() );
-
- response.setContentType( "text/html; charset=\"UTF-8\"" );
-
- out.println( "" );
- out.println( "" + message + "" );
- out.println( "" );
-
- out.print( "" );
- out.print( message );
- out.println( "
" );
-
- out.print( "The following resource does not exist: " );
- out.print( missingUrl.toString() );
- out.println( "
" );
-
- if ( t != null )
- {
- out.println( "" );
- t.printStackTrace( out );
- out.println( "
" );
- }
-
- out.println( "" );
-
- out.flush();
- }
- catch ( IOException e )
- {
- e.printStackTrace();
- }
- }
-
- private boolean fetchContentFromProxies( DavServerRequest request, String resource )
- throws ServletException
- {
- if ( repositoryRequest.isSupportFile( resource ) )
- {
- // Checksums are fetched with artifact / metadata.
-
- // Need to adjust the path for the checksum resource.
- return false;
- }
-
- // Is it a Metadata resource?
- if ( repositoryRequest.isDefault( resource ) && repositoryRequest.isMetadata( resource ) )
- {
- return fetchMetadataFromProxies( request, resource );
- }
-
- // Not any of the above? Then it's gotta be an artifact reference.
- try
- {
- // Get the artifact reference in a layout neutral way.
- ArtifactReference artifact = repositoryRequest.toArtifactReference( resource );
-
- if ( artifact != null )
- {
- applyServerSideRelocation( artifact );
-
- File proxiedFile = connectors.fetchFromProxies( managedRepository, artifact );
-
- // Set the path to the resource using managed repository
- // specific layout format.
- request.setLogicalResource( managedRepository.toPath( artifact ) );
- return ( proxiedFile != null );
- }
- }
- catch ( LayoutException e )
- {
- /* eat it */
- }
- catch ( ProxyDownloadException e )
- {
- throw new ServletException( "Unable to fetch artifact resource.", e );
- }
- return false;
- }
-
- private boolean fetchMetadataFromProxies( DavServerRequest request, String resource )
- throws ServletException
- {
- ProjectReference project;
- VersionedReference versioned;
-
- try
- {
-
- versioned = metadataTools.toVersionedReference( resource );
- if ( versioned != null )
- {
- connectors.fetchFromProxies( managedRepository, versioned );
- return true;
- }
- }
- catch ( RepositoryMetadataException e )
- {
- /* eat it */
- }
-
- try
- {
- project = metadataTools.toProjectReference( resource );
- if ( project != null )
- {
- connectors.fetchFromProxies( managedRepository, project );
- return true;
- }
- }
- catch ( RepositoryMetadataException e )
- {
- /* eat it */
- }
-
- return false;
- }
-
- /**
- * A relocation capable client will request the POM prior to the artifact,
- * and will then read meta-data and do client side relocation. A simplier
- * client (like maven 1) will only request the artifact and not use the
- * metadatas.
- *
- * For such clients, archiva does server-side relocation by reading itself
- * the <relocation> element in metadatas and serving the expected
- * artifact.
- */
- protected void applyServerSideRelocation( ArtifactReference artifact )
- throws ProxyDownloadException
- {
- if ( "pom".equals( artifact.getType() ) )
- {
- return;
- }
-
- // Build the artifact POM reference
- ArtifactReference pomReference = new ArtifactReference();
- pomReference.setGroupId( artifact.getGroupId() );
- pomReference.setArtifactId( artifact.getArtifactId() );
- pomReference.setVersion( artifact.getVersion() );
- pomReference.setType( "pom" );
-
- // Get the artifact POM from proxied repositories if needed
- connectors.fetchFromProxies( managedRepository, pomReference );
-
- // Open and read the POM from the managed repo
- File pom = managedRepository.toFile( pomReference );
-
- if ( !pom.exists() )
- {
- return;
- }
-
- try
- {
- Model model = new MavenXpp3Reader().read( new FileReader( pom ) );
- DistributionManagement dist = model.getDistributionManagement();
- if ( dist != null )
- {
- Relocation relocation = dist.getRelocation();
- if ( relocation != null )
- {
- // artifact is relocated : update the repositoryPath
- if ( relocation.getGroupId() != null )
- {
- artifact.setGroupId( relocation.getGroupId() );
- }
- if ( relocation.getArtifactId() != null )
- {
- artifact.setArtifactId( relocation.getArtifactId() );
- }
- if ( relocation.getVersion() != null )
- {
- artifact.setVersion( relocation.getVersion() );
- }
- }
- }
- }
- catch ( FileNotFoundException e )
- {
- // Artifact has no POM in repo : ignore
- }
- catch ( IOException e )
- {
- // Unable to read POM : ignore.
- }
- catch ( XmlPullParserException e )
- {
- // Invalid POM : ignore
- }
- }
-
- @Override
- public void addListener( DavServerListener listener )
- {
- super.addListener( listener );
- davServer.addListener( listener );
- }
-
- @Override
- public boolean isUseIndexHtml()
- {
- return davServer.isUseIndexHtml();
- }
-
- @Override
- public boolean hasResource( String resource )
- {
- return davServer.hasResource( resource );
- }
-
- @Override
- public void removeListener( DavServerListener listener )
- {
- davServer.removeListener( listener );
- }
-
- @Override
- public void setUseIndexHtml( boolean useIndexHtml )
- {
- super.setUseIndexHtml( useIndexHtml );
- davServer.setUseIndexHtml( useIndexHtml );
- }
-
- public ManagedRepositoryContent getRepository()
- {
- return managedRepository;
- }
-
- private void processAuditEvents( DavServerRequest request, String resource,
- boolean previouslyExisted, File resourceFile, String suffix )
- {
- if ( suffix == null )
- {
- suffix = "";
- }
-
- // Process Create Audit Events.
- if ( !previouslyExisted && resourceFile.exists() )
- {
- if ( resourceFile.isFile() )
- {
- triggerAuditEvent( request, resource, AuditEvent.CREATE_FILE + suffix );
- }
- else if ( resourceFile.isDirectory() )
- {
- triggerAuditEvent( request, resource, AuditEvent.CREATE_DIR + suffix );
- }
- }
- // Process Remove Audit Events.
- else if ( previouslyExisted && !resourceFile.exists() )
- {
- if ( resourceFile.isFile() )
- {
- triggerAuditEvent( request, resource, AuditEvent.REMOVE_FILE + suffix );
- }
- else if ( resourceFile.isDirectory() )
- {
- triggerAuditEvent( request, resource, AuditEvent.REMOVE_DIR + suffix );
- }
- }
- // Process modify events.
- else
- {
- if ( resourceFile.isFile() )
- {
- triggerAuditEvent( request, resource, AuditEvent.MODIFY_FILE + suffix );
- }
- }
- }
-
- private void triggerAuditEvent( String user, String remoteIP, String resource, String action )
- {
- AuditEvent event = new AuditEvent( this.getPrefix(), user, resource, action );
- event.setRemoteIP( remoteIP );
-
- for ( AuditListener listener : auditListeners )
- {
- listener.auditEvent( event );
- }
- }
-
- private void triggerAuditEvent( DavServerRequest request, String resource, String action )
- {
- triggerAuditEvent( ArchivaXworkUser.getActivePrincipal(), getRemoteIP( request ), resource,
- action );
- }
-
- private String getRemoteIP( DavServerRequest request )
- {
- return request.getRequest().getRemoteAddr();
- }
-
- public void addAuditListener( AuditListener listener )
- {
- this.auditListeners.add( listener );
- }
-
- public void clearAuditListeners()
- {
- this.auditListeners.clear();
- }
-
- public void removeAuditListener( AuditListener listener )
- {
- this.auditListeners.remove( listener );
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/RepositoryServlet.java b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/RepositoryServlet.java
index c3121a2cb..fb4d2e3c4 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/RepositoryServlet.java
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/repository/RepositoryServlet.java
@@ -23,29 +23,24 @@ import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.ConfigurationEvent;
import org.apache.maven.archiva.configuration.ConfigurationListener;
import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
-import org.apache.maven.archiva.security.ArchivaRoleConstants;
-import org.apache.maven.archiva.webdav.DavServerComponent;
-import org.apache.maven.archiva.webdav.DavServerException;
-import org.apache.maven.archiva.webdav.servlet.DavServerRequest;
-import org.apache.maven.archiva.webdav.servlet.multiplexed.MultiplexedWebDavServlet;
-import org.apache.maven.archiva.webdav.util.WebdavMethodUtil;
-import org.codehaus.plexus.redback.authentication.AuthenticationException;
-import org.codehaus.plexus.redback.authentication.AuthenticationResult;
-import org.codehaus.plexus.redback.authorization.AuthorizationException;
-import org.codehaus.plexus.redback.authorization.AuthorizationResult;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
-import org.codehaus.plexus.redback.system.SecuritySession;
+import org.apache.maven.archiva.webdav.ArchivaDavLocatorFactory;
+import org.apache.maven.archiva.webdav.ArchivaDavResourceFactory;
+import org.apache.maven.archiva.webdav.ArchivaDavSessionProvider;
+import org.apache.maven.archiva.webdav.UnauthorizedDavException;
+import org.apache.jackrabbit.webdav.server.AbstractWebdavServlet;
+import org.apache.jackrabbit.webdav.*;
import org.codehaus.plexus.redback.system.SecuritySystem;
import org.codehaus.plexus.redback.xwork.filter.authentication.HttpAuthenticator;
import org.codehaus.plexus.spring.PlexusToSpringUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.Map;
@@ -57,9 +52,11 @@ import java.util.Map;
* @version $Id$
*/
public class RepositoryServlet
- extends MultiplexedWebDavServlet
+ extends AbstractWebdavServlet
implements ConfigurationListener
{
+ private Logger log = LoggerFactory.getLogger(RepositoryServlet.class);
+
private SecuritySystem securitySystem;
private HttpAuthenticator httpAuth;
@@ -67,17 +64,76 @@ public class RepositoryServlet
private ArchivaConfiguration configuration;
private Map repositoryMap;
-
- private ArchivaMimeTypeLoader mimeTypeLoader;
+
+ private DavLocatorFactory locatorFactory;
+
+ private DavResourceFactory resourceFactory;
+
+ private DavSessionProvider sessionProvider;
+
+ private final Object reloadLock = new Object();
+
+ public void init(javax.servlet.ServletConfig servletConfig)
+ throws ServletException
+ {
+ super.init(servletConfig);
+ initServers(servletConfig);
+ }
+
+ /**
+ * Service the given request.
+ *
+ * @param request
+ * @param response
+ * @throws ServletException
+ * @throws java.io.IOException
+ */
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException
+ {
+ WebdavRequest webdavRequest = new WebdavRequestImpl(request, getLocatorFactory());
+ // DeltaV requires 'Cache-Control' header for all methods except 'VERSION-CONTROL' and 'REPORT'.
+ int methodCode = DavMethods.getMethodCode(request.getMethod());
+ boolean noCache = DavMethods.isDeltaVMethod(webdavRequest) && !(DavMethods.DAV_VERSION_CONTROL == methodCode || DavMethods.DAV_REPORT == methodCode);
+ WebdavResponse webdavResponse = new WebdavResponseImpl(response, noCache);
+ try {
+ // make sure there is a authenticated user
+ if (!getDavSessionProvider().attachSession(webdavRequest)) {
+ return;
+ }
+
+ // check matching if=header for lock-token relevant operations
+ DavResource resource = getResourceFactory().createResource(webdavRequest.getRequestLocator(), webdavRequest, webdavResponse);
+ if (!isPreconditionValid(webdavRequest, resource)) {
+ webdavResponse.sendError(DavServletResponse.SC_PRECONDITION_FAILED);
+ return;
+ }
+ if (!execute(webdavRequest, webdavResponse, methodCode, resource)) {
+ super.service(request, response);
+ }
+
+ }
+ catch (UnauthorizedDavException e)
+ {
+ webdavResponse.setHeader("WWW-Authenticate", getAuthenticateHeaderValue(e.getRepositoryName()));
+ webdavResponse.sendError(e.getErrorCode(), e.getStatusPhrase());
+ }
+ catch (DavException e) {
+ if (e.getErrorCode() == HttpServletResponse.SC_UNAUTHORIZED) {
+ log.error("Should throw UnauthorizedDavException");
+ } else {
+ webdavResponse.sendError(e);
+ }
+ } finally {
+ getDavSessionProvider().releaseSession(webdavRequest);
+ }
+ }
public synchronized void initServers( ServletConfig servletConfig )
- throws DavServerException
{
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext( servletConfig.getServletContext() );
- mimeTypeLoader = (ArchivaMimeTypeLoader) wac.getBean(
- PlexusToSpringUtils.buildSpringId( ArchivaMimeTypeLoader.class.getName() ) );
-
securitySystem = (SecuritySystem) wac.getBean( PlexusToSpringUtils.buildSpringId( SecuritySystem.ROLE ) );
httpAuth =
(HttpAuthenticator) wac.getBean( PlexusToSpringUtils.buildSpringId( HttpAuthenticator.ROLE, "basic" ) );
@@ -101,157 +157,91 @@ public class RepositoryServlet
continue;
}
}
-
- DavServerComponent server = createServer( repo.getId(), repoDir, servletConfig );
-
- server.setUseIndexHtml( true );
}
+
+ resourceFactory = (DavResourceFactory)wac.getBean(PlexusToSpringUtils.buildSpringId(ArchivaDavResourceFactory.class));
+ locatorFactory = new ArchivaDavLocatorFactory();
+ sessionProvider = new ArchivaDavSessionProvider(wac);
}
- @Override
- protected void service( HttpServletRequest httpRequest, HttpServletResponse httpResponse )
- throws ServletException, IOException
+ public void configurationEvent( ConfigurationEvent event )
{
- // Wrap the incoming request to adjust paths and whatnot.
- super.service( new PolicingServletRequest( httpRequest ), httpResponse );
+ if( event.getType() == ConfigurationEvent.SAVED )
+ {
+ initRepositories();
+ }
}
- public synchronized ManagedRepositoryConfiguration getRepository( String prefix )
+ private void initRepositories()
{
- if ( repositoryMap.isEmpty() )
+ synchronized ( repositoryMap )
{
+ repositoryMap.clear();
repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
}
- return repositoryMap.get( prefix );
- }
- private String getRepositoryName( DavServerRequest request )
- {
- ManagedRepositoryConfiguration repoConfig = getRepository( request.getPrefix() );
- if ( repoConfig == null )
+ synchronized ( reloadLock )
{
- return "Unknown";
+ initServers( getServletConfig() );
}
-
- return repoConfig.getName();
}
- public boolean isAuthenticated( DavServerRequest davRequest, HttpServletResponse response )
- throws ServletException, IOException
+ public synchronized ManagedRepositoryConfiguration getRepository( String prefix )
{
- HttpServletRequest request = davRequest.getRequest();
-
- // Authentication Tests.
- try
- {
- AuthenticationResult result = httpAuth.getAuthenticationResult( request, response );
-
- if ( result != null && !result.isAuthenticated() )
- {
- // Must Authenticate.
- httpAuth.challenge( request, response, "Repository " + getRepositoryName( davRequest ),
- new AuthenticationException( "User Credentials Invalid" ) );
- return false;
- }
- }
- catch ( AuthenticationException e )
- {
- log( "Fatal Http Authentication Error.", e );
- throw new ServletException( "Fatal Http Authentication Error.", e );
- }
- catch ( AccountLockedException e )
- {
- httpAuth.challenge( request, response, "Repository " + getRepositoryName( davRequest ),
- new AuthenticationException( "User account is locked" ) );
- }
- catch ( MustChangePasswordException e )
+ if ( repositoryMap.isEmpty() )
{
- httpAuth.challenge( request, response, "Repository " + getRepositoryName( davRequest ),
- new AuthenticationException( "You must change your password." ) );
+ repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
}
-
- return true;
+ return repositoryMap.get( prefix );
}
- public boolean isAuthorized( DavServerRequest davRequest, HttpServletResponse response )
- throws ServletException, IOException
+ ArchivaConfiguration getConfiguration()
{
- // Authorization Tests.
- HttpServletRequest request = davRequest.getRequest();
-
- boolean isWriteRequest = WebdavMethodUtil.isWriteMethod( request.getMethod() );
-
- SecuritySession securitySession = httpAuth.getSecuritySession();
- try
- {
- String permission = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS;
-
- if ( isWriteRequest )
- {
- permission = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD;
- }
+ return configuration;
+ }
- AuthorizationResult authzResult =
- securitySystem.authorize( securitySession, permission, davRequest.getPrefix() );
+ protected boolean isPreconditionValid(final WebdavRequest request, final DavResource davResource)
+ {
+ return true;
+ }
- if ( !authzResult.isAuthorized() )
- {
- if ( authzResult.getException() != null )
- {
- log( "Authorization Denied [ip=" + request.getRemoteAddr() + ",isWriteRequest=" + isWriteRequest +
- ",permission=" + permission + ",repo=" + davRequest.getPrefix() + "] : " +
- authzResult.getException().getMessage() );
- }
+ public DavSessionProvider getDavSessionProvider()
+ {
+ return sessionProvider;
+ }
- // Issue HTTP Challenge.
- httpAuth.challenge( request, response, "Repository " + getRepositoryName( davRequest ),
- new AuthenticationException( "Authorization Denied." ) );
- return false;
- }
- }
- catch ( AuthorizationException e )
- {
- throw new ServletException( "Fatal Authorization Subsystem Error." );
- }
+ public void setDavSessionProvider(final DavSessionProvider davSessionProvider)
+ {
+ this.sessionProvider = davSessionProvider;
+ }
- return true;
+ public DavLocatorFactory getLocatorFactory()
+ {
+ return locatorFactory;
}
-
- public void configurationEvent( ConfigurationEvent event )
+
+ public void setLocatorFactory(final DavLocatorFactory davLocatorFactory)
{
- if( event.getType() == ConfigurationEvent.SAVED )
- {
- initRepositories();
- }
+ locatorFactory = davLocatorFactory;
}
- private void initRepositories()
+ public DavResourceFactory getResourceFactory()
{
- synchronized ( repositoryMap )
- {
- repositoryMap.clear();
- repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
- }
+ return resourceFactory;
+ }
- synchronized ( davManager )
- {
- // Clear out the old servers.
- davManager.removeAllServers();
+ public void setResourceFactory(final DavResourceFactory davResourceFactory)
+ {
+ resourceFactory = davResourceFactory;
+ }
- // Create new servers.
- try
- {
- initServers( getServletConfig() );
- }
- catch ( DavServerException e )
- {
- log( "Unable to init servers: " + e.getMessage(), e );
- }
- }
+ public String getAuthenticateHeaderValue()
+ {
+ throw new UnsupportedOperationException("");
}
- ArchivaConfiguration getConfiguration()
+ public String getAuthenticateHeaderValue(String repository)
{
- return configuration;
+ return "Basic realm=\"Repository Archiva Managed " + repository + " Repository\"";
}
}
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/resources/META-INF/plexus/application.xml b/archiva-modules/archiva-web/archiva-webapp/src/main/resources/META-INF/plexus/application.xml
index 8d42dcfd2..246786d7a 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/resources/META-INF/plexus/application.xml
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/resources/META-INF/plexus/application.xml
@@ -66,19 +66,6 @@
-
- org.apache.maven.archiva.webdav.DavServerManager
- default
- org.apache.maven.archiva.webdav.DefaultDavServerManager
- DefaultDavServerManager
-
-
- org.apache.maven.archiva.webdav.DavServerComponent
- proxied
-
-
-
-
org.codehaus.plexus.jdo.JdoFactory
archiva
@@ -187,14 +174,14 @@
-
+
+
+ org.apache.archiva
+ archiva-repository-layer
+
+
+ org.apache.archiva
+ archiva-proxy
+
+
+ org.apache.archiva
+ archiva-security
+
+
+ org.apache.archiva
+ archiva-configuration
+
+
+ org.codehaus.plexus.redback
+ redback-xwork-integration
+
+
+ org.codehaus.plexus
+ plexus-container-default
+
+
+
+
+
+ org.apache.maven.wagon
+ wagon-http
+
+
+ org.apache.maven.wagon
+ wagon-file
+
commons-lang
commons-lang
@@ -37,14 +73,17 @@
org.codehaus.plexus
plexus-component-api
-
-
- org.codehaus.plexus
- plexus-utils
+
+
+ org.codehaus.plexus
+ plexus-container-default
+
+
org.codehaus.plexus
plexus-spring
+ 1.0-SNAPSHOT
org.springframework
@@ -52,36 +91,22 @@
2.5.1
- commons-io
- commons-io
+ org.apache.jackrabbit
+ jackrabbit-webdav
-
-
-
javax.servlet
servlet-api
- 2.3
provided
-
- slide
- slide-webdavlib
- 2.1
- test
-
-
- org.mortbay.jetty
- jetty
- 6.0.2
- test
-
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/StreamTools.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/StreamTools.java
deleted file mode 100644
index 17ebb7e9c..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/StreamTools.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * An utility class providing various static methods operating on
- * {@link InputStream input} and {@link OutputStream output} streams.
- *
- * @author Pier Fumagalli
- */
-public final class StreamTools {
-
- /** Deny construction.
*/
- private StreamTools() { };
-
- /**
- * Copy every byte from the specified {@link InputStream} to the specifed
- * {@link OutputStream} and then close both of them.
- *
- * This method is equivalent to a call to the following method:
- * {@link #copy(InputStream,OutputStream,boolean) copy(in, out, true)}.
- *
- * @param in the {@link InputStream} to read bytes from.
- * @param out the {@link OutputStream} to write bytes to.
- * @return the number of bytes copied.
- * @throws IOException if an I/O error occurred copying the data.
- */
- public static long copy(InputStream in, OutputStream out)
- throws IOException {
- return copy(in, out, true);
- }
-
- /**
- * Copy every byte from the specified {@link InputStream} to the specifed
- * {@link OutputStream} and then optionally close both of them.
- *
- * @param in the {@link InputStream} to read bytes from.
- * @param out the {@link OutputStream} to write bytes to.
- * @param close whether to close the streams or not.
- * @return the number of bytes copied.
- * @throws IOException if an I/O error occurred copying the data.
- */
- public static long copy(InputStream in, OutputStream out, boolean close)
- throws IOException {
- if (in == null) throw new NullPointerException("Null input");
- if (out == null) throw new NullPointerException("Null output");
-
- final byte buffer[] = new byte[4096];
- int length = -1;
- long total = 0;
- while ((length = in.read(buffer)) >= 0) {
- out.write(buffer, 0, length);
- total += length;
- }
-
- if (close) {
- in.close();
- out.close();
- }
-
- return total;
- }
-
- /**
- * Closes the output stream. The output stream can be null and any IOException's will be swallowed.
- *
- * @param outputStream The stream to close.
- */
- public static void close( OutputStream outputStream )
- {
- if ( outputStream == null )
- {
- return;
- }
-
- try
- {
- outputStream.close();
- }
- catch( IOException ex )
- {
- // ignore
- }
- }
-
- /**
- * Closes the input stream. The input stream can be null and any IOException's will be swallowed.
- *
- * @param inputStream The stream to close.
- */
- public static void close( InputStream inputStream )
- {
- if ( inputStream == null )
- {
- return;
- }
-
- try
- {
- inputStream.close();
- }
- catch( IOException ex )
- {
- // ignore
- }
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/StringTools.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/StringTools.java
deleted file mode 100644
index 3b0eb14ea..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/StringTools.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.util;
-
-import it.could.util.encoding.Encodable;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.TimeZone;
-
-/**
- * An utility class providing various static methods operating on
- * {@link String}s.
- *
- * This class implement the {@link Encodable} interface from which it
- * inherits its {@link Encodable#DEFAULT_ENCODING default encoding}.
- *
- * @author Pier Fumagalli
- */
-public final class StringTools {
-
- /** The {@link SimpleDateFormat} RFC-822 date format.
*/
- private static final String FORMAT_822 = "EEE, dd MMM yyyy HH:mm:ss 'GMT'";
- /** The {@link SimpleDateFormat} RFC-822 date format.
*/
- private static final String FORMAT_ISO = "yyyy-MM-dd'T'HH:mm:ss'Z'";
- /** The {@link TimeZone} to use for dates.
*/
- private static final TimeZone TIMEZONE = TimeZone.getTimeZone("GMT");
- /** The {@link Locale} to use for dates.
*/
- private static final Locale LOCALE = Locale.US;
-
- /** Deny construction.
*/
- private StringTools() { }
-
- /* ====================================================================== */
- /* NUMBER AND DATE PARSING AND FORMATTING */
- /* ====================================================================== */
-
- /**
- * Format a {@link Number} into a {@link String} making sure that
- * {@link NullPointerException}s are not thrown.
- *
- * @param number the {@link Number} to format.
- * @return a {@link String} instance or null if the object was null.
- */
- public static String formatNumber(Number number) {
- if (number == null) return null;
- return (number.toString());
- }
-
- /**
- * Parse a {@link String} into a {@link Long}.
- *
- * @param string the {@link String} to parse.
- * @return a {@link Long} instance or null if the date was null or
- * if there was an error parsing the specified {@link String}.
- */
- public static Long parseNumber(String string) {
- if (string == null) return null;
- try {
- return new Long(string);
- } catch (NumberFormatException exception) {
- return null;
- }
- }
-
- /**
- * Format a {@link Date} according to the HTTP/1.1 RFC.
- *
- * @param date the {@link Date} to format.
- * @return a {@link String} instance or null if the date was null.
- */
- public static String formatHttpDate(Date date) {
- if (date == null) return null;
- SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_822, LOCALE);
- formatter.setTimeZone(TIMEZONE);
- return formatter.format(date);
- }
-
- /**
- * Format a {@link Date} according to the ISO 8601 specification.
- *
- * @param date the {@link Date} to format.
- * @return a {@link String} instance or null if the date was null.
- */
- public static String formatIsoDate(Date date) {
- if (date == null) return null;
- SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_ISO, LOCALE);
- formatter.setTimeZone(TIMEZONE);
- return formatter.format(date);
- }
-
- /**
- * Parse a {@link String} into a {@link Date} according to the
- * HTTP/1.1 RFC (Mon, 31 Jan 2000 11:59:00 GMT
).
- *
- * @param string the {@link String} to parse.
- * @return a {@link Date} instance or null if the date was null or
- * if there was an error parsing the specified {@link String}.
- */
- public static Date parseHttpDate(String string) {
- if (string == null) return null;
- SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_822, LOCALE);
- formatter.setTimeZone(TIMEZONE);
- try {
- return formatter.parse(string);
- } catch (ParseException exception) {
- return null;
- }
- }
-
- /**
- * Parse a {@link String} into a {@link Date} according to the ISO 8601
- * specification (2000-12-31T11:59:00Z
).
- *
- * @param string the {@link String} to parse.
- * @return a {@link Date} instance or null if the date was null or
- * if there was an error parsing the specified {@link String}.
- */
- public static Date parseIsoDate(String string) {
- if (string == null) return null;
- SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_ISO, LOCALE);
- formatter.setTimeZone(TIMEZONE);
- try {
- return formatter.parse(string);
- } catch (ParseException exception) {
- return null;
- }
- }
-
- /* ====================================================================== */
- /* STRING SPLITTING */
- /* ====================================================================== */
-
- /**
- * Split the specified string in two parts according to the specified
- * delimiter, and any resulting path of zero length will be converted to
- * null.
- */
- public static String[] splitOnce(String source, char delimiter,
- boolean noDelimReturnSecond) {
- if (source == null) return new String[] { null, null };
- final int position = source.indexOf(delimiter);
- if (position < 0) { // --> first
- if (noDelimReturnSecond) return new String[] { null, source };
- else return new String[] { source, null };
- } else if (position == 0) {
- if (source.length() == 1) { // --> |
- return new String[] { null, null };
- } else { // --> |second
- return new String[] { null, source.substring(1) };
- }
- } else {
- final String first = source.substring(0, position);
- if (source.length() -1 == position) { // --> first|
- return new String[] { first, null };
- } else { // --> first|second
- return new String[] { first, source.substring(position + 1) };
- }
- }
- }
-
- /**
- * Split the specified string according to the specified delimiter, and
- * any resulting path of zero length will be converted to null.
- */
- public static String[] splitAll(String source, char delimiter) {
- final List strings = new ArrayList();
- String current = source;
- while (current != null) {
- String split[] = splitOnce(current, delimiter, false);
- strings.add(split[0]);
- current = split[1];
- }
- if (current != null) strings.add(current);
- final int length = source.length();
- if ((length > 0) && (source.charAt(length - 1) == delimiter)) {
- strings.add(null);
- }
- return (String []) strings.toArray(new String[strings.size()]);
- }
-
- /**
- * Find the first occurrence of one of the specified delimiter characters
- * in the specified source string.
- */
- public static int findFirst(String source, String delimiters) {
- final char array[] = source.toCharArray();
- final char delim[] = delimiters.toCharArray();
- for (int x = 0; x < array.length; x ++) {
- for (int y = 0; y < delim.length; y ++) {
- if (array[x] == delim[y]) return x;
- }
- }
- return -1;
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/encoding/Encodable.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/encoding/Encodable.java
deleted file mode 100644
index 2f644f9a0..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/encoding/Encodable.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.util.encoding;
-
-import java.io.UnsupportedEncodingException;
-
-/**
- * The {@link Encodable} interface describes an {@link Object} whose
- * {@link String} representation can vary depending on the encoding used.
- *
- * @author Pier Fumagalli
- */
-public interface Encodable extends EncodingAware {
-
- /**
- * Return the {@link String} representation of this instance.
- *
- * This method is equivalent to a call to
- * {@link #toString(String) toString}({@link EncodingAware#DEFAULT_ENCODING
- * DEFAULT_ENCODING})
- */
- public String toString();
-
- /**
- * Return the {@link String} representation of this instance given
- * a specific character encoding.
- *
- * @throws UnsupportedEncodingException if the specified encoding is not
- * supported by the platform.
- */
- public String toString(String encoding)
- throws UnsupportedEncodingException;
-
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/encoding/EncodingAware.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/encoding/EncodingAware.java
deleted file mode 100644
index 0690a175b..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/encoding/EncodingAware.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.util.encoding;
-
-import java.io.ByteArrayOutputStream;
-import java.io.OutputStreamWriter;
-
-/**
- * The {@link EncodingAware} interface describes an {@link Object} aware
- * of multiple encodings existing withing the platform.
- *
- * @author Pier Fumagalli
- */
-public interface EncodingAware {
-
- /** The default encoding is specified as being UTF-8
.
*/
- public static final String DEFAULT_ENCODING = "UTF-8";
-
- /** The platform encoding is evaluated at runtime from the JVM.
*/
- public static final String PLATFORM_ENCODING =
- new OutputStreamWriter(new ByteArrayOutputStream()).getEncoding();
-
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/encoding/EncodingTools.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/encoding/EncodingTools.java
deleted file mode 100644
index c0c2e7adb..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/encoding/EncodingTools.java
+++ /dev/null
@@ -1,274 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.util.encoding;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-
-/**
- * An utility class providing various static methods dealing with
- * encodings and {@link Encodable} objects..
- *
- * @author Pier Fumagalli
- */
-public final class EncodingTools implements EncodingAware {
-
- /** The Base-64 alphabet.
*/
- private static final char ALPHABET[] = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
- 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
- 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '=' };
-
- /** Deny construction of this class.
*/
- private EncodingTools() { }
-
- /* ====================================================================== */
- /* URL ENCODING / DECODING */
- /* ====================================================================== */
-
- /**
- * Return the {@link String} representation of the specified
- * {@link Encodable} object using the {@link EncodingAware#DEFAULT_ENCODING
- * default encoding}.
- *
- * throws NullPointerException if the {@link Encodable} was null.
- */
- public static String toString(Encodable encodable) {
- try {
- return encodable.toString(DEFAULT_ENCODING);
- } catch (UnsupportedEncodingException exception) {
- final String message = "Default encoding \"" + DEFAULT_ENCODING +
- "\" not supported by the platform";
- final InternalError error = new InternalError(message);
- throw (InternalError) error.initCause(exception);
- }
- }
-
- /* ====================================================================== */
- /* URL ENCODING / DECODING */
- /* ====================================================================== */
-
- /**
- * URL-encode the specified string.
- */
- public static String urlEncode(String source, String encoding)
- throws UnsupportedEncodingException {
- if (source == null) return null;
- if (encoding == null) encoding = DEFAULT_ENCODING;
- return URLEncoder.encode(source, encoding);
- }
-
- /**
- * URL-encode the specified string.
- */
- public static String urlEncode(String source) {
- if (source == null) return null;
- try {
- return URLEncoder.encode(source, DEFAULT_ENCODING);
- } catch (UnsupportedEncodingException exception) {
- final String message = "Unsupported encoding " + DEFAULT_ENCODING;
- final InternalError error = new InternalError(message);
- throw (InternalError) error.initCause(exception);
- }
- }
-
- /**
- * URL-decode the specified string.
- */
- public static String urlDecode(String source, String encoding)
- throws UnsupportedEncodingException {
- if (source == null) return null;
- if (encoding == null) encoding = DEFAULT_ENCODING;
- return URLDecoder.decode(source, encoding);
- }
-
- /**
- * URL-decode the specified string.
- */
- public static String urlDecode(String source) {
- if (source == null) return null;
- try {
- return URLDecoder.decode(source, DEFAULT_ENCODING);
- } catch (UnsupportedEncodingException exception) {
- final String message = "Unsupported encoding " + DEFAULT_ENCODING;
- final InternalError error = new InternalError(message);
- throw (InternalError) error.initCause(exception);
- }
- }
-
- /* ====================================================================== */
- /* BASE 64 ENCODING / DECODING */
- /* ====================================================================== */
-
- /**
- * Encode the specified string in base 64 using the specified
- * encoding.
- */
- public static final String base64Encode(String string, String encoding)
- throws UnsupportedEncodingException {
- /* Check the source string for null or the empty string. */
- if (string == null) return (null);
- if (string.length() == 0) return "";
-
- /* Check the encoding */
- if (encoding == null) encoding = DEFAULT_ENCODING;
-
- /* Prepare the buffers that we'll use to encode in Base 64 */
- final byte bsrc[] = string.getBytes(encoding);
- final char bdst[] = new char[(bsrc.length + 2) / 3 * 4];
-
- /* Iterate into the source in chunks of three bytes */
- int psrc = -1;
- int pdst = 0;
- int temp = 0;
- while ((psrc = psrc + 3) < bsrc.length) {
- /* For every three bytes processed ... */
- temp = ((bsrc[psrc - 2] << 16) & 0xFF0000) |
- ((bsrc[psrc - 1] << 8) & 0x00FF00) |
- ((bsrc[psrc ] ) & 0x0000FF);
- /* ... we append four bytes to the buffer */
- bdst[pdst ++] = ALPHABET[(temp >> 18) & 0x3f];
- bdst[pdst ++] = ALPHABET[(temp >> 12) & 0x3f];
- bdst[pdst ++] = ALPHABET[(temp >> 6) & 0x3f];
- bdst[pdst ++] = ALPHABET[(temp ) & 0x3f];
- }
-
- /* Let's check whether we still have some bytes to encode */
- switch (psrc - bsrc.length) {
- case 0: /* Two bytes left to encode */
- temp = ((bsrc[psrc - 2] & 0xFF) << 8) | (bsrc[psrc - 1] & 0xFF);
- bdst[pdst ++] = ALPHABET[(temp >> 10) & 0x3f];
- bdst[pdst ++] = ALPHABET[(temp >> 4) & 0x3f];
- bdst[pdst ++] = ALPHABET[(temp << 2) & 0x3c];
- bdst[pdst ++] = ALPHABET[64];
- break;
- case 1: /* One byte left to encode */
- temp = (bsrc[psrc - 2] & 0xFF);
- bdst[pdst ++] = ALPHABET[(temp >> 2) & 0x3f];
- bdst[pdst ++] = ALPHABET[(temp << 4) & 0x30];
- bdst[pdst ++] = ALPHABET[64];
- bdst[pdst ++] = ALPHABET[64];
- }
-
- /* Convert the character array into a proper string */
- return new String(bdst);
- }
-
- /**
- * Encode the specified string in base 64 using the default encoding.
- */
- public static final String base64Encode(String string) {
- try {
- return (base64Encode(string, DEFAULT_ENCODING));
- } catch (UnsupportedEncodingException exception) {
- final String message = "Unsupported encoding " + DEFAULT_ENCODING;
- final InternalError error = new InternalError(message);
- throw (InternalError) error.initCause(exception);
- }
- }
-
- /**
- * Decode the specified base 64 string using the specified encoding.
- */
- public static final String base64Decode(String string, String encoding)
- throws UnsupportedEncodingException {
- /* Check the source string for null or the empty string. */
- if (string == null) return (null);
- if (string.length() == 0) return "";
-
- /* Check the encoding */
- if (encoding == null) encoding = DEFAULT_ENCODING;
-
- /* Retrieve the array of characters of the source string. */
- final char characters[] = string.toCharArray();
-
- /* Check the length, which must be dividible by 4. */
- if ((characters.length & 0x03) != 0)
- throw new IllegalArgumentException("Invalid length for the "+
- "encoded string (" + characters.length + ")");
-
- /* The bytes array length is 3/4th of the characters array length */
- byte bytes[] = new byte[characters.length - (characters.length >> 2)];
-
- /*
- * Since this might take a while check now for the last 4 characters
- * token: it must contain at most two == and those need to be in the
- * last two positions in the array (the only valid sequences are:
- * "????", "???=" and "??==").
- */
- if (((characters[characters.length - 4] == '=') ||
- (characters[characters.length - 3] == '=')) ||
- ((characters[characters.length - 2] == '=') &&
- (characters[characters.length - 1] != '='))) {
- throw new IllegalArgumentException("Invalid pattern for last " +
- "Base64 token in string to decode: " +
- characters[characters.length - 4] +
- characters[characters.length - 3] +
- characters[characters.length - 2] +
- characters[characters.length - 1]);
- }
-
- /* Translate the Base64-encoded String in chunks of 4 characters. */
- int coff = 0;
- int boff = 0;
- while (coff < characters.length) {
- boolean last = (coff == (characters.length - 4));
- int curr = ((value(characters[coff ], last) << 0x12) |
- (value(characters[coff + 1], last) << 0x0c) |
- (value(characters[coff + 2], last) << 0x06) |
- (value(characters[coff + 3], last) ));
- bytes[boff + 2] = (byte)((curr ) & 0xff);
- bytes[boff + 1] = (byte)((curr >> 0x08) & 0xff);
- bytes[boff ] = (byte)((curr >> 0x10) & 0xff);
- coff += 4;
- boff += 3;
- }
-
- /* Get the real decoded string length, checking out the trailing '=' */
- if (characters[coff - 1] == '=') boff--;
- if (characters[coff - 2] == '=') boff--;
-
- /* All done */
- return (new String(bytes, 0, boff, encoding));
- }
-
- /**
- * Decode the specified base 64 string using the default encoding.
- */
- public static final String base64Decode(String string) {
- try {
- return (base64Decode(string, DEFAULT_ENCODING));
- } catch (UnsupportedEncodingException exception) {
- final String message = "Unsupported encoding " + DEFAULT_ENCODING;
- final InternalError error = new InternalError(message);
- throw (InternalError) error.initCause(exception);
- }
- }
-
- /* ====================================================================== */
-
- /** Retrieve the offset of a character in the base 64 alphabet.
*/
- private static final int value(char character, boolean last) {
- for (int x = 0; x < 64; x++) if (ALPHABET[x] == character) return (x);
- if (last && (character == ALPHABET[65])) return(0);
- final String message = "Character \"" + character + "\" invalid";
- throw new IllegalArgumentException(message);
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/encoding/package.html b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/encoding/package.html
deleted file mode 100644
index 675ba3f58..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/encoding/package.html
+++ /dev/null
@@ -1,61 +0,0 @@
-
-
- Encoding Utilities
-
-
-
- This package contains a number of utility classes dealing with generic
- encoding of {@link java.lang.String}s.
-
-
- Although this might sound useless at first (as {@link java.lang.String}s
- do support encoding internally already), this class deals with a very
- subtle problem encountered when merging Java {@link java.lang.String}s
- and old byte-based (non internationalized) transports, such as
- Base 64 and URL encoding.
-
-
- Let's consider (as an example) the URL encoded {@link java.lang.String}
- %C2%A3 100
can be easily decomposed in a byte array using
- URL decoding techniques: we would end up with the following byte array:
- 0x0C2 0x0A3 0x20 0x31 0x30 0x30
.
-
-
- This byte-array, though, doesn't tell us anything about how to represent
- this as a readable and usable {@link java.lang.String} in Java. To be
- able to convert this we have to decode it again using a charset (or an
- encoding).
-
-
- So, for example, if we were to decode the above mentioned byte array using
- the ISO-8859-1 encoding, we would obtain the string
- "£ 100
", or in details:
-
-
- - a latin capital letter "A" with a circumflex accent
- - the pound sign
- - a space
- - the number 1
- - the number 0
- - the number 0
-
-
- If we were to decode the same byte sequence using UTF-8, on the
- other hand, we would obtain the (quite different) string
- "£ 100
", or in details:
-
-
- - the pound sign
- - a space
- - the number 1
- - the number 0
- - the number 0
-
-
- Therefore, as a conclusion, when Java {@link java.lang.String}s are
- encoded using Base 64, URL encoding, or similar techiques, one always
- have to remember that encoding (or decoding) must be done twice, and
- this package provides a way to deal with this mechanism.
-
-
-
\ No newline at end of file
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/http/HttpClient.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/http/HttpClient.java
deleted file mode 100644
index 75884e0a2..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/http/HttpClient.java
+++ /dev/null
@@ -1,1070 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.util.http;
-
-import it.could.util.encoding.EncodingTools;
-import it.could.util.location.Location;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.MalformedURLException;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A class implementing an extremely simple HTTP 1.0 connector with
- * basic authentication support.
- *
- * @author Pier Fumagalli
- */
-public class HttpClient {
-
- /** The default HTTP method to use.
*/
- public static final String DEFAULT_METHOD = "GET";
-
- /* ====================================================================== */
-
- /** The byte sequence CR LF (the end of the request).
*/
- private static final byte CRLF[] = { 0x0d, 0x0a };
- /** The byte sequence for " HTTP/1.0\r\n" (the request signature).
*/
- private static final byte HTTP[] = { 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f,
- 0x31, 0x2e, 0x30, 0x0d, 0x0a };
-
- /* ====================================================================== */
-
- /** The buffer used to parse lines in the response.
*/
- private final byte buffer[] = new byte[4096];
- /** The map of the current request headers.
*/
- private final Map requestHeaders = new HashMap();
- /** The map of the current response headers.
*/
- private final Map responseHeaders = new HashMap();
-
- /* ====================================================================== */
-
- /** The {@link Location} pointing to the current request.
*/
- private Location location;
- /** The status of the current request.
*/
- private Status status = null;
- /** An array of acceptable statuses to verify upon connection.
*/
- private int acceptable[] = null;
-
- /* ====================================================================== */
-
- /** The limited input stream associated with this request.
*/
- private Input xinput = null;
- /** The limited output stream associated with this request.
*/
- private Output xoutput = null;
- /** The socket associated with this request.
*/
- private Socket xsocket = null;
-
- /* ====================================================================== */
-
- /**
- * Create a new {@link HttpClient} instance associated with the
- * specified location in string format.
- *
- * @throws MalformedURLException if the location couldn't be parsed.
- */
- public HttpClient(String location)
- throws MalformedURLException {
- this.location = Location.parse(location);
- }
-
- /**
- * Create a new {@link HttpClient} instance associated with the
- * specified location in string format.
- *
- * @throws MalformedURLException if the location couldn't be parsed.
- */
- public HttpClient(String location, String encoding)
- throws MalformedURLException, UnsupportedEncodingException {
- this.location = Location.parse(location, encoding);
- }
-
- /**
- * Create a new {@link HttpClient} instance associated with the
- * specified {@link Location}.
- */
- public HttpClient(Location location) {
- if (location == null) throw new NullPointerException("Null location");
- if (! location.isAbsolute())
- throw new IllegalArgumentException("Relative location supplied");
- if (! "http".equals(location.getSchemes().toString())) {
- throw new IllegalArgumentException("Scheme is not HTTP");
- }
- this.location = location;
- }
-
- /* ====================================================================== */
- /* CONNECTION VERIFICATION METHODS */
- /* ====================================================================== */
-
- /**
- * Set an HTTP response status code considered to be acceptable when
- * verifying the connection.
- */
- public HttpClient setAcceptableStatus(int status) {
- return this.setAcceptableStatuses(new int[] { status });
- }
-
- /**
- * Set an array of HTTP response status codes considered to be acceptable
- * when verifying the connection.
- *
- * If the array is null status code checking is disabled.
- */
- public HttpClient setAcceptableStatuses(int statuses[]) {
- if (statuses == null) {
- this.acceptable = null;
- return this;
- }
- for (int x = 0; x < statuses.length; x ++) {
- final int status = statuses[x];
- if ((status < 100) || (status > 599))
- throw new IllegalArgumentException("Wrong status " + status);
- }
- this.acceptable = statuses;
- return this;
- }
-
- /* ====================================================================== */
- /* CONNECTION METHODS */
- /* ====================================================================== */
-
- /**
- * Connect to the {@link Location} specified at construction using the
- * default method GET
.
- *
- * This is equivalent to {@link #connect(boolean) connect(true)}.
- *
- * @return this {@link HttpClient} instance.
- * @throws IOException if an I/O or a network error occurred.
- */
- public HttpClient connect()
- throws IOException {
- return this.connect(DEFAULT_METHOD, true, 0);
- }
-
- /**
- * Connect to the {@link Location} specified at construction using the
- * default method GET
allowing for a specified amount of
- * content to be written into the request.
- *
- * @return this {@link HttpClient} instance.
- * @throws IOException if an I/O or a network error occurred.
- */
- public HttpClient connect(long contentLength)
- throws IOException {
- return this.connect(DEFAULT_METHOD, false, contentLength);
- }
-
- /**
- * Connect to the {@link Location} specified at construction using the
- * default method GET
and optionally following redirects.
- *
- * @return this {@link HttpClient} instance.
- * @throws IOException if an I/O or a network error occurred.
- */
- public HttpClient connect(boolean followRedirects)
- throws IOException {
- return this.connect(DEFAULT_METHOD, followRedirects, 0);
- }
-
- /**
- * Connect to the {@link Location} specified at construction with the
- * specified method.
- *
- * This is equivalent to {@link #connect(String,boolean)
- * connect(method, true)}.
- *
- * @return this {@link HttpClient} instance.
- * @throws IOException if an I/O or a network error occurred.
- */
- public HttpClient connect(String method)
- throws IOException {
- return this.connect(method, true, 0);
- }
-
- /**
- * Connect to the {@link Location} specified at construction with the
- * specified method allowing for a specified amount of content to be
- * written into the request.
- *
- * @return this {@link HttpClient} instance.
- * @throws IOException if an I/O or a network error occurred.
- */
- public HttpClient connect(String method, long contentLength)
- throws IOException {
- return this.connect(method, false, contentLength);
- }
-
- /**
- * Connect to the {@link Location} specified at construction with the
- * specified method and optionally following redirects.
- *
- * @return this {@link HttpClient} instance.
- * @throws IOException if an I/O or a network error occurred.
- */
- public HttpClient connect(String method, boolean followRedirects)
- throws IOException {
- return this.connect(method, followRedirects, 0);
- }
-
- /**
- * Disconnect from the remote endpoint and terminate the request.
- *
- * Note that request and response headers, the resultin status and
- * acceptable statuses are not cleared by this method.
- *
- * @return this {@link HttpClient} instance.
- * @throws IOException if an I/O or a network error occurred.
- */
- public HttpClient disconnect()
- throws IOException {
- return this.disconnect(false);
- }
-
- /**
- * Disconnect from the remote endpoint and terminate the request.
- *
- * @param reset whether to reset all headers, status and acceptable response
- * status codes or not.
- * @return this {@link HttpClient} instance.
- * @throws IOException if an I/O or a network error occurred.
- */
- public HttpClient disconnect(boolean reset)
- throws IOException {
- final Socket socket = this.xsocket;
- if (socket != null) try {
- /* Make sure that we mark this instance as being closed */
- this.xsocket = null;
-
- /* Close the input stream if necessary */
- if (this.xinput != null) {
- if (! this.xinput.closed) this.xinput.close();
- this.xinput = null;
- }
-
- /* Close the output stream if necessary */
- if (this.xoutput != null) {
- if (! this.xoutput.closed) this.xoutput.close();
- this.xoutput = null;
- }
-
- } finally {
- /* Ensure that the socket is closed */
- socket.close();
- }
-
- if (reset) {
- this.requestHeaders.clear();
- this.responseHeaders.clear();
- this.status = null;
- this.acceptable = null;
- }
- return this;
- }
-
- /* ====================================================================== */
- /* INTERNAL CONNECTION HANDLER */
- /* ====================================================================== */
-
- /**
- * Internal method actually connecting to the remote HTTP server.
- */
- private HttpClient connect(String method, boolean redirect, long length)
- throws IOException {
- /* Check if (by any chance) we have been connected already */
- if (this.xsocket != null)
- throw new IllegalStateException("Already connected");
-
- /* Check for both follow redirects and content length */
- if (length < 0) throw new IOException("Negative length");
- if ((length > 0) && redirect)
- throw new InternalError("Can't follow redirects and write request");
-
- /* Verify any authentication token */
- final String userinfo = this.location.getAuthority().getUserInfo();
- if (userinfo != null) {
- final String encoded = EncodingTools.base64Encode(userinfo);
- this.addRequestHeader("Authorization", "Basic " + encoded);
- }
-
- /* All methods in HTTP are upper case */
- method = method.toUpperCase();
-
- /* Make sure we close the connection at the end of the request */
- this.addRequestHeader("Connection", "close", false);
-
- /* The content length of the request is forced to be valid */
- this.addRequestHeader("Content-Length", Long.toString(length), false);
-
- /* Enter in a loop for redirections */
- int redirs = 20;
- while (true) {
- /* If we have been redirected too many times, fail */
- if ((--redirs) < 0) throw new IOException("Too many redirections");
-
- /* Get the authority, once and for all */
- final Location.Authority auth = this.location.getAuthority();
-
- /* Prepare a normalized host header */
- final String host = auth.getHost();
- final int port = auth.getPort() < 0 ? 80 : auth.getPort();
- this.addRequestHeader("Host", host + ":" + port, false);
-
- /* Connect to the remote endpoint */
- final Socket sock = new Socket(auth.getHost(), port);
- final InputStream in = sock.getInputStream();
- final OutputStream out = sock.getOutputStream();
-
- /* Write the request line */
- out.write((method + " ").getBytes("US-ASCII"));
- out.write(this.location.getPath().toString().getBytes("US-ASCII"));
- out.write(HTTP); /* SPACE HTTP/1.0 CR LF */
-
- /* Write all the headers */
- final Iterator headers = this.requestHeaders.values().iterator();
- while (headers.hasNext()) {
- final RequestHeader header = (RequestHeader) headers.next();
- final Iterator values = header.values.iterator();
- while (values.hasNext()) {
- out.write(header.name);
- out.write((byte []) values.next());
- }
- }
-
- /* Write the final CRLF, read the status and the headers */
- out.write(CRLF);
- out.flush();
-
- /* Return now if we have to write content */
- if (length > 0) {
- this.xsocket = sock;
- this.xoutput = new Output(this, in, out, length);
- this.xinput = null;
- return this;
- }
-
- this.readStatusLine(in);
- this.readHeaders(in);
-
- /* If we have to follow redirects, let's inspect the response */
- final int code = this.status.status;
- if (redirect && ((code == 301) || (code == 302) || (code == 307))) {
- final String location = this.getResponseHeader("Location");
- if (location != null) {
- in.close();
- out.close();
- sock.close();
- this.location = this.location.resolve(location);
- continue;
- }
- }
-
- /* No further redirections, so verify if the status code is ok */
- this.verify();
-
- /* Evaluate the content length specified by the server */
- final String len = this.getResponseHeader("Content-Length");
- long bytesLength = -1;
- if (len != null) try {
- bytesLength = Long.parseLong(len);
- } catch (NumberFormatException exception) {
- /* Swallow this, be liberal in what we accept */
- }
-
- /* Return an output stream if the content length was not zero */
- this.xsocket = sock;
- this.xoutput = null;
- this.xinput = new Input(this, in, bytesLength);
- return this;
- }
- }
-
- private void verify()
- throws IOException {
- /* No further redirections, sov erify if the status code is ok */
- if (this.acceptable != null) {
- boolean accepted = false;
- for (int x = 0; x < this.acceptable.length; x ++) {
- if (this.status.status != this.acceptable[x]) continue;
- accepted = true;
- break;
- }
- if (! accepted) {
- this.disconnect();
- throw new IOException("Connection to " + this.location +
- " returned unacceptable status " +
- this.status.status + " (" +
- this.status.message + ")");
- }
- }
- }
-
- /* ====================================================================== */
- /* INPUT / OUTPUT METHODS */
- /* ====================================================================== */
-
- /**
- * Return an {@link InputStream} where the content of the HTTP response
- * can be read from.
- *
- * @throws IllegalStateException if this instance is not connected yet, or
- * the request body was not fully written yet.
- */
- public InputStream getResponseStream()
- throws IllegalStateException {
- if (this.xsocket == null)
- throw new IllegalStateException("Connection not available");
- if ((this.xoutput != null) && (this.xoutput.remaining != 0))
- throw new IllegalStateException("Request body not fully written");
- return this.xinput;
- }
-
- /**
- * Return an {@link OutputStream} where the content of the HTTP request
- * can be written to.
- *
- * @throws IllegalStateException if this instance is not connected yet or if
- * upon connection the size of the request was
- * not specifed or zero.
- */
- public OutputStream getRequestStream()
- throws IllegalStateException {
- if (this.xsocket == null)
- throw new IllegalStateException("Connection not available");
- if (this.xoutput == null)
- throw new IllegalStateException("No request body to write to");
- return this.xoutput;
- }
-
- /* ====================================================================== */
- /* REQUEST AND RESPONSE METHODS */
- /* ====================================================================== */
-
- /**
- * Return the {@link Location} of this connection.
- *
- * This might be different from the {@link Location} specified at
- * construction time if upon connecting HTTP redirections were followed.
- */
- public Location getLocation() {
- return this.location;
- }
-
- /**
- * Add a new header that will be sent with the HTTP request.
- *
- * This method will remove any header value previously associated with
- * the specified name, in other words this method is equivalent to
- * {@link #addRequestHeader(String, String, boolean)
- * addRequestHeader(name, value, false)}.
- *
- * @param name the name of the request header to add.
- * @param value the value of the request header to add.
- * @return this {@link HttpClient} instance.
- * @throws NullPointerException the name or value were null.
- */
- public HttpClient addRequestHeader(String name, String value) {
- return this.addRequestHeader(name, value, false);
- }
-
- /**
- * Add a new header that will be sent with the HTTP request.
- *
- * @param name the name of the request header to add.
- * @param value the value of the request header to add.
- * @param appendValue if the current value should be appended, or in other
- * words, that two headers with the same can coexist.
- * @return this {@link HttpClient} instance.
- * @throws NullPointerException the name or value were null.
- */
- public HttpClient addRequestHeader(String name, String value,
- boolean appendValue) {
- final String key = name.toLowerCase();
- try {
- RequestHeader header;
- if (appendValue) {
- header = (RequestHeader) this.requestHeaders.get(key);
- if (header == null) {
- header = new RequestHeader(name);
- this.requestHeaders.put(key, header);
- }
- } else {
- header = new RequestHeader(name);
- this.requestHeaders.put(key, header);
- }
- header.values.add((value + "\r\n").getBytes("ISO-8859-1"));
- return this;
- } catch (UnsupportedEncodingException exception) {
- Error error = new InternalError("Standard encoding not supported");
- throw (InternalError) error.initCause(exception);
- }
- }
-
- /**
- * Remove the named header from the current HTTP request.
- *
- * @param name the name of the request header to add.
- * @return this {@link HttpClient} instance.
- * @throws NullPointerException the name was null.
- */
- public HttpClient removeRequestHeader(String name) {
- final String key = name.toLowerCase();
- this.requestHeaders.remove(key);
- return this;
- }
-
- /**
- * Remove all headers from the current HTTP request.
- *
- * @return this {@link HttpClient} instance.
- */
- public HttpClient removeRequestHeaders() {
- this.requestHeaders.clear();
- return this;
- }
-
- /**
- * Return the first value for the specified response header.
- *
- * @param name the name of the header whose value needs to be returned.
- * @return a {@link String} or null if no such header exists.
- */
- public String getResponseHeader(String name) {
- final String key = name.toLowerCase();
- ResponseHeader header = (ResponseHeader) this.responseHeaders.get(key);
- if (header == null) return null;
- return (String) header.values.get(0);
- }
-
- /**
- * Return all the values for the specified response header.
- *
- * @param name the name of the header whose values needs to be returned.
- * @return a {@link List} or null if no such header exists.
- */
- public List getResponseHeaderValues(String name) {
- final String key = name.toLowerCase();
- ResponseHeader header = (ResponseHeader) this.responseHeaders.get(key);
- if (header == null) return null;
- return Collections.unmodifiableList(header.values);
- }
-
- /**
- * Return an {@link Iterator} over all response header names.
- *
- * @return a non-null {@link Iterator}.
- */
- public Iterator getResponseHeaderNames() {
- final Iterator iterator = this.responseHeaders.values().iterator();
- return new Iterator() {
- public boolean hasNext() {
- return iterator.hasNext();
- }
- public Object next() {
- return ((ResponseHeader) iterator.next()).name;
- }
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
- }
-
- /**
- * Return the protocol returned by the remote HTTP server.
- *
- * @return a non-null {@link String} like HTTP/1.0
.
- * @throws IllegalStateException if the connection was never connected.
- */
- public String getResponseProtocol() {
- if (this.status == null) throw new IllegalStateException();
- return this.status.protocol;
- }
-
- /**
- * Return the status returned by the remote HTTP server.
- *
- * @return a number representing the HTTP status of the response.
- * @throws IllegalStateException if the connection was never connected.
- */
- public int getResponseStatus() {
- if (this.status == null) throw new IllegalStateException();
- return this.status.status;
- }
-
- /**
- * Return the status message returned by the remote HTTP server.
- *
- * @return a non-null {@link String} like OK
.
- * @throws IllegalStateException if the connection was never connected.
- */
- public String getResponseMessage() {
- if (this.status == null) throw new IllegalStateException();
- return this.status.message;
- }
-
- /* ====================================================================== */
- /* PRIVATE METHODS TO USE WHEN CONNECTING */
- /* ====================================================================== */
-
- /**
- * Read a single line of the HTTP response from the specified
- * {@link InputStream} into a byte array (trailing CRLF are removed).
- */
- private byte[] readLine(InputStream input)
- throws IOException {
- int x = 0;
- while (true) {
- int b = input.read();
- if (b == -1) break;
- if (b == 0x0A) break;
- if (x == this.buffer.length) break;
- this.buffer[x ++] = (byte) b;
- }
- if ((x > 0) && (this.buffer[x - 1] == 0x0D)) x--;
- final byte array[] = new byte[x];
- System.arraycopy(this.buffer, 0, array, 0, x);
- return array;
- }
-
- /**
- * Read the status line from the specified {@link InputStream} and
- * setup the {@link #status} field.
- */
- private void readStatusLine(InputStream input)
- throws IOException {
- /* Prepare the different buffers required for parsing */
- final byte line[] = this.readLine(input);
- final byte buff[] = new byte[line.length];
- final String comp[] = new String[3];
- int lpos = 0;
- int bpos = 0;
- int cpos = 0;
- boolean spc = true;
-
- /* Iterate every single byte in the line, splitting up components */
- while (lpos < line.length) {
- final byte b = line[lpos ++];
- if (spc) {
- if ((b == 0x09) || (b == 0x20)) continue;
- buff[bpos ++] = b;
- if (cpos == 2) break;
- else spc = false;
- } else {
- if ((b == 0x09) || (b == 0x20)) {
- comp[cpos ++] = new String(buff, 0, bpos, "US-ASCII");
- bpos = 0;
- spc = true;
- continue;
- }
- buff[bpos ++] = b;
- }
-
- }
- /*
- * Copy remaining bytes out of the line buffer and ensure all
- * components in the status line are not null;
- */
- while (lpos < line.length) buff[bpos ++] = line[lpos++];
- if (bpos > 0) comp[cpos++] = new String(buff, 0, bpos, "US-ASCII");
- for (int x = cpos; x < 3; x++) comp[x] = "";
-
- /* Create the status object */
- this.status = new Status(comp[0], comp[1], comp[2]);
- }
-
- /**
- * Read all the response headers from the specified {@link InputStream}
- * and setup the {@link #responseHeaders} field.
- */
- private void readHeaders(InputStream input)
- throws IOException {
- /* Clear out any previous header */
- this.responseHeaders.clear();
-
- /* Process the input stream until we find an empty line */
- while (true) {
- final byte array[] = this.readLine(input);
- if (array.length == 0) break;
-
- /* Identify where the colon is in the header */
- int pos = -1;
- while (pos < array.length) if (array[++ pos] == 0x03A) break;
- if (pos == 0) continue;
- if (pos == array.length - 1) continue;
-
- /* Prepare strings for name and value */
- final int o = pos + 1;
- final int l = array.length - o;
- final String name = new String(array, 0, pos, "US-ASCII").trim();
- final String value = new String(array, o, l, "ISO-8859-1").trim();
- if ((name.length() == 0) || (value.length() == 0)) continue;
-
- /* Store the header value in a list for now */
- final String key = name.toLowerCase();
- ResponseHeader hdr = (ResponseHeader) this.responseHeaders.get(key);
- if (hdr == null) {
- hdr = new ResponseHeader(name);
- this.responseHeaders.put(key, hdr);
- }
- hdr.values.add(value);
- }
- }
-
- /* ====================================================================== */
- /* INTERNAL CLASS REPRESENTNG THE STATUS LINE AND AN ENCODED HEADER */
- /* ====================================================================== */
-
- /**
- * A simple internal class representing a response status line.
- */
- private static final class Status {
-
- /** The response protocol, like HTTP/1.0
*/
- private final String protocol;
- /**
The response status code, like 302
*/
- private final int status;
- /**
The response message, like Moved permanently
*/
- private final String message;
-
- /**
- *
Create a new {@link Status} verifying the supplied parameters.
- *
- * @throws IOException if an error occurred verifying the parameters.
- */
- private Status(String protocol, String status, String message)
- throws IOException {
-
- /* Verify the protocol */
- if ("HTTP/1.0".equals(protocol) || "HTTP/1.1".equals(protocol)) {
- this.protocol = protocol;
- } else {
- throw new IOException("Unknown protocol \"" + protocol + "\"");
- }
-
- /* Verify the status */
- try {
- this.status = Integer.parseInt(status);
- if ((this.status < 100) || (this.status > 599)) {
- throw new IOException("Invalid status \"" + status + "\"");
- }
- } catch (RuntimeException exception) {
- final String error = "Can't parse status \"" + status + "\"";
- IOException throwable = new IOException(error);
- throw (IOException) throwable.initCause(exception);
- }
-
- /* Decode the message */
- if ("".equals(message)) this.message = "No message";
- else this.message = EncodingTools.urlDecode(message, "ISO-8859-1");
- }
- }
-
- /**
- * A simple internal class representing a request header.
- */
- private static final class RequestHeader {
-
- /** The byte array of the header's name.
*/
- private final byte name[];
- /** A {@link List} of all the header's values.
*/
- private final List values;
-
- /** Create a new {@link RequestHeader} instance.
*/
- private RequestHeader(String name)
- throws UnsupportedEncodingException {
- this.name = (name + ": ").getBytes("US-ASCII");
- this.values = new ArrayList();
- }
- }
-
- /**
- * A simple internal class representing a response header.
- */
- private static final class ResponseHeader {
-
- /** The real name of the response header.
*/
- private final String name;
- /** A {@link List} of all the header's values.
*/
- private final List values;
-
- /** Create a new {@link ResponseHeader} instance.
*/
- private ResponseHeader(String name)
- throws UnsupportedEncodingException {
- this.name = name;
- this.values = new ArrayList();
- }
- }
-
- /* ====================================================================== */
- /* LIMITED STREAMS */
- /* ====================================================================== */
-
- /**
- * A simple {@link OutputStream} writing at most the number of bytes
- * specified at construction.
- */
- private static final class Output extends OutputStream {
-
- /** The {@link OutputStream} wrapped by this instance.
*/
- private final OutputStream output;
- /** The {@link InputStream} wrapped by this instance.
*/
- private final InputStream input;
- /** The {@link HttpClient} wrapped by this instance.
*/
- private final HttpClient client;
- /** The number of bytes yet to write.
*/
- private long remaining;
- /** A flag indicating whether this instance was closed.
*/
- private boolean closed;
-
- /**
- * Create a new {@link Output} instance with the specified limit
- * of bytes to write.
- *
- * @param output the {@link OutputStream} to wrap.
- * @param remainig the maximum number of bytes to write.
- */
- private Output(HttpClient client, InputStream input,
- OutputStream output, long remaining) {
- if (input == null) throw new NullPointerException();
- if (output == null) throw new NullPointerException();
- if (client == null) throw new NullPointerException();
- this.remaining = remaining;
- this.client = client;
- this.output = output;
- this.input = input;
- }
-
- public void write(byte buf[])
- throws IOException {
- this.write(buf, 0, buf.length);
- }
-
- public void write(byte buf[], int off, int len)
- throws IOException {
- if (len > this.remaining) {
- throw new IOException("Too much data to write");
- } else try {
- this.output.write(buf, off, len);
- } finally {
- this.remaining -= len;
- if (this.remaining < 1) this.close();
- }
- }
-
- public void write(int b)
- throws IOException {
- if (this.remaining < 1) {
- throw new IOException("Too much data to write");
- } else try {
- this.output.write(b);
- } finally {
- this.remaining -= 1;
- if (this.remaining < 1) this.close();
- }
- }
-
- public void flush()
- throws IOException {
- this.output.flush();
- }
-
- public void close()
- throws IOException {
- if (this.closed) return;
- if (this.remaining > 0)
- throw new IOException(this.remaining + " bytes left to write");
- this.closed = true;
- this.output.flush();
-
- /* Read the status and headers from the connection and verify */
- this.client.readStatusLine(this.input);
- this.client.readHeaders(this.input);
- this.client.verify();
-
- /* Evaluate the content length specified by the server */
- final String slen = this.client.getResponseHeader("Content-Length");
- long blen = -1;
- if (slen != null) try {
- blen = Long.parseLong(slen);
- } catch (NumberFormatException exception) {
- /* Swallow this, be liberal in what we accept */
- }
-
- /* Return an output stream if the content length was not zero */
- this.client.xoutput = null;
- this.client.xinput = new Input(this.client, this.input, blen);
- }
-
- protected void finalize()
- throws Throwable {
- try {
- this.close();
- } finally {
- super.finalize();
- }
- }
- }
-
- /**
- * A simple {@link InputStream} reading at most the number of bytes
- * specified at construction.
- */
- private static final class Input extends InputStream {
-
- /** The {@link InputStream} wrapped by this instance.
*/
- private final InputStream input;
- /** The {@link HttpClient} wrapped by this instance.
*/
- private final HttpClient client;
- /** The number of bytes yet to write or -1 if unknown.
*/
- private long remaining;
- /** A flag indicating whether this instance was closed.
*/
- private boolean closed;
-
- /**
- * Create a new {@link Input} instance with the specified limit
- * of bytes to read.
- *
- * @param input the {@link InputStream} to wrap.
- * @param remainig the maximum number of bytes to read or -1 if unknown.
- */
- private Input(HttpClient client, InputStream input, long remaining) {
- if (input == null) throw new NullPointerException();
- if (client == null) throw new NullPointerException();
- this.remaining = remaining < 0 ? Long.MAX_VALUE : remaining;
- this.client = client;
- this.input = input;
- }
-
- public int read()
- throws IOException {
- if (this.remaining < 1) {
- return -1;
- } else try {
- return this.input.read();
- } finally {
- this.remaining -= 1;
- if (this.remaining < 1) this.close();
- }
- }
-
- public int read(byte buf[])
- throws IOException {
- return read(buf, 0, buf.length);
- }
-
- public int read(byte buf[], int off, int len)
- throws IOException {
- if (this.remaining <= 0) return -1;
- if (len > this.remaining) len = (int) this.remaining;
- int count = 0;
- try {
- count = this.input.read(buf, off, len);
- } finally {
- this.remaining -= count;
- if (this.remaining < 1) this.close();
- }
- return count;
- }
-
- public long skip(long n)
- throws IOException {
- if (this.remaining <= 0) return -1;
- if (n > this.remaining) n = this.remaining;
- long count = 0;
- try {
- count = this.input.skip(n);
- } finally {
- this.remaining -= count;
- if (this.remaining < 1) this.close();
- }
- return count;
- }
-
- public int available()
- throws IOException {
- int count = this.input.available();
- if (count < this.remaining) return count;
- return (int) this.remaining;
- }
-
- public void close()
- throws IOException {
- if (this.closed) return;
- this.closed = true;
- try {
- this.input.close();
- } finally {
- this.client.disconnect();
- }
- }
-
- public void mark(int readlimit) {
- this.input.mark(readlimit);
- }
-
- public void reset()
- throws IOException {
- this.input.reset();
- }
-
- public boolean markSupported() {
- return this.input.markSupported();
- }
-
- protected void finalize()
- throws Throwable {
- try {
- this.close();
- } finally {
- super.finalize();
- }
- }
- }
-
- /* ====================================================================== */
- /* UTILITY FETCHER */
- /* ====================================================================== */
-
- /**
- * Utility method: fetch the location specified on the command
- * line following redirects if necessary.
- *
- * The final location fetched (in case of redirections it might change)
- * will be reported on the {@link System#err system error stream} alongside
- * with any errors encountered while processing.
- */
- public static final void main(String args[]) {
- try {
- final HttpClient c = new HttpClient(args[0]).connect();
- final InputStream i = c.getResponseStream();
- for (int b = i.read(); b >= 0; b = i.read()) System.out.write(b);
- c.disconnect();
- } catch (Throwable throwable) {
- throwable.printStackTrace(System.err);
- }
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/http/WebDavClient.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/http/WebDavClient.java
deleted file mode 100644
index fe0eba41b..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/http/WebDavClient.java
+++ /dev/null
@@ -1,901 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.util.http;
-
-import it.could.util.StreamTools;
-import it.could.util.StringTools;
-import it.could.util.location.Location;
-import it.could.util.location.Path;
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.net.MalformedURLException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-import java.util.StringTokenizer;
-
-/**
- * A class implementing an extremely simple WebDAV Level 1 client based on
- * the {@link HttpClient}.
- *
- * Once opened this class will represent a WebDAV collection. Users of this
- * class can then from an instance of this, deal with relative parent and
- * children resources.
- *
- * @author Pier Fumagalli
- */
-public class WebDavClient {
-
- /** The WebDAV resource asociated with this instance.
*/
- private Resource resource;
- /** A map of children resources of this instance.
*/
- private Map children;
-
- /**
- * Create a new {@link WebDavClient} instance opening the collection
- * identified by the specified {@link Location}.
- *
- * @param location the {@link Location} of the WebDAV collection to open.
- * @throws IOException if an I/O or network error occurred, or if the
- * {@link Location} specified does not point to a
- * WebDAV collection.
- * @throws NullPointerException if the {@link Location} was null.
- */
- public WebDavClient(Location location)
- throws NullPointerException, IOException {
- if (location == null) throw new NullPointerException("Null location");
- this.reload(location);
- }
-
- /* ====================================================================== */
- /* ACTIONS */
- /* ====================================================================== */
-
- /**
- * Refresh this {@link WebDavClient} instance re-connecting to the remote
- * collection and re-reading its properties.
- *
- * @return this {@link WebDavClient} instance.
- */
- public WebDavClient refresh()
- throws IOException {
- this.reload(this.resource.location);
- return this;
- }
-
- /**
- * Fetch the contents of the specified child resource of the collection
- * represented by this {@link WebDavClient} instance.
- *
- * @see #isCollection(String)
- * @return a non-null {@link InputStream}.
- * @throws IOException if an I/O or network error occurred, or if the
- * child specified represents a collection.
- * @throws NullPointerException if the child was null.
- */
- public InputStream get(String child)
- throws NullPointerException, IOException {
- if (child == null) throw new NullPointerException("Null child");
- if (! this.isCollection(child)) {
- final Location location = this.getLocation(child);
- final HttpClient client = new HttpClient(location);
- client.setAcceptableStatus(200).connect("GET");
- return client.getResponseStream();
- }
- throw new IOException("Child \"" + child + "\" is a collection");
- }
-
- /**
- * Delete the child resource (or collection) of the collection
- * represented by this {@link WebDavClient} instance.
- *
- * @return this {@link WebDavClient} instance.
- * @throws IOException if an I/O or network error occurred, or if the
- * child specified represents a collection.
- * @throws NullPointerException if the child was null.
- */
- public WebDavClient delete(String child)
- throws NullPointerException, IOException {
- if (child == null) throw new NullPointerException("Null child");
- final HttpClient client = new HttpClient(this.getLocation(child));
- client.setAcceptableStatus(204).connect("DELETE").disconnect();
- return this.refresh();
- }
-
- /**
- * Create a new collection as a child of the collection represented
- * by this {@link WebDavClient} instance.
- *
- * In comparison to {@link #put(String)} and {@link #put(String, long)}
- * this method will fail if the specified child already exist.
- *
- * @see #hasChild(String)
- * @return this {@link WebDavClient} instance.
- * @throws IOException if an I/O or network error occurred, or if the
- * child specified already exist.
- * @throws NullPointerException if the child was null.
- */
- public WebDavClient mkcol(String child)
- throws NullPointerException, IOException {
- if (child == null) throw new NullPointerException("Null child");
- if (this.hasChild(child))
- throw new IOException("Child \"" + child + "\" already exists");
- final Location location = this.resource.location.resolve(child);
- final HttpClient client = new HttpClient(location);
- client.setAcceptableStatus(201).connect("MKCOL").disconnect();
- return this.refresh();
- }
-
- /**
- * Create a new (or update the contents of a) child of of the collection
- * represented by this {@link WebDavClient} instance.
- *
- * This method will behave exactly like the {@link #put(String, long)}
- * method, but the data written to the returned {@link OutputStream} will
- * be buffered in memory and will be transmitted to the remote
- * server only when the {@link OutputStream#close()} method is called.
- *
- * If the returned {@link OutputStream} is garbage collected before the
- * {@link OutputStream#close() close()} method is called, the entire
- * transaction will be aborted and no connection to the remote server will
- * be established.
- *
- * Use this method in extreme cases. In normal circumstances always rely
- * on the {@link #put(String, long)} method.
- *
- * @see #put(String, long)
- * @return a non-null {@link OutputStream} instance.
- * @throws NullPointerException if the child was null.
- */
- public OutputStream put(final String child)
- throws NullPointerException {
- if (child == null) throw new NullPointerException("Null child");
- final WebDavClient client = this;
- return new ByteArrayOutputStream() {
- private boolean closed = false;
- public void close()
- throws IOException {
- if (this.closed) return;
- this.flush();
- OutputStream output = client.put(child, this.buf.length);
- output.write(this.buf);
- output.flush();
- output.close();
- }
-
- protected void finalize()
- throws Throwable {
- this.closed = true;
- super.finalize();
- }
- };
- }
-
- /**
- * Create a new (or update the contents of a) child of of the collection
- * represented by this {@link WebDavClient} instance.
- *
- * If the specified child {@link #hasChild(String) already exists} on
- * the remote server, it will be {@link #delete(String) deleted} before
- * writing.
- *
- * @return a non-null {@link OutputStream} instance.
- * @throws NullPointerException if the child was null.
- * @throws IOException if an I/O or network error occurred, or if the
- * child specified already exist.
- */
- public OutputStream put(String child, long length)
- throws NullPointerException, IOException {
- if (child == null) throw new NullPointerException("Null child");
- if (this.hasChild(child)) this.delete(child);
- final Location location = this.resource.location.resolve(child);
- final HttpClient client = new HttpClient(location);
- client.setAcceptableStatuses(new int[] { 201, 204 });
- client.connect("PUT", length);
-
- final WebDavClient webdav = this;
- return new BufferedOutputStream(client.getRequestStream()) {
- boolean closed = false;
- public void close()
- throws IOException {
- if (this.closed) return;
- try {
- super.close();
- } finally {
- this.closed = true;
- webdav.refresh();
- }
- }
- protected void finalize()
- throws Throwable {
- try {
- this.close();
- } finally {
- super.finalize();
- }
- }
- };
- }
-
- /**
- * Open the specified child collection of the collection represented by
- * this {@link WebDavClient} as a new {@link WebDavClient} instance.
- *
- * If the specified child is ".
" this method
- * will behave exactly like {@link #refresh()} and this instance
- * will be returned.
- *
- * If the specified child is "..
" this method
- * will behave exactly like {@link #parent()}.
- *
- * @return a non-null {@link WebDavClient} instance.
- * @throws NullPointerException if the child was null.
- * @throws IOException if an I/O or network error occurred, or if the
- * child specified did not exist.
- */
- public WebDavClient open(String child)
- throws NullPointerException, IOException {
- if (child == null) throw new NullPointerException("Null child");
- if (".".equals(child)) return this.refresh();
- if ("..".equals(child)) return this.parent();
- if (resource.collection) {
- Location loc = this.getLocation().resolve(this.getLocation(child));
- return new WebDavClient(loc);
- }
- throw new IOException("Child \"" + child + "\" is not a collection");
- }
-
- /**
- * Open the parent collection of the collection represented by this
- * {@link WebDavClient} as a new {@link WebDavClient} instance.
- *
- * @return a non-null {@link WebDavClient} instance.
- * @throws IOException if an I/O or network error occurred, or if the
- * child specified did not exist.
- */
- public WebDavClient parent()
- throws IOException {
- final Location location = this.resource.location.resolve("..");
- return new WebDavClient(location);
- }
-
- /* ====================================================================== */
- /* ACCESSOR METHODS */
- /* ====================================================================== */
-
- /**
- * Return an {@link Iterator} over {@link String}s for all the children
- * of the collection represented by this {@link WebDavClient} instance.
- */
- public Iterator iterator() {
- return this.children.keySet().iterator();
- }
-
- /**
- * Checks if the collection represented by this {@link WebDavClient}
- * contains the specified child.
- */
- public boolean hasChild(String child) {
- return this.children.containsKey(child);
- }
-
- /**
- * Return the {@link Location} associated with the collection
- * represented by this {@link WebDavClient}.
- *
- * The returned {@link Location} can be different from the one specified
- * at construction, in case the server redirected us upon connection.
- */
- public Location getLocation() {
- return this.resource.location;
- }
-
- /**
- * Return the content length (in bytes) of the collection represented
- * by this {@link WebDavClient} as passed to us by the WebDAV server.
- */
- public long getContentLength() {
- return this.resource.contentLength;
- }
-
- /**
- * Return the content type (mime-type) of the collection represented
- * by this {@link WebDavClient} as passed to us by the WebDAV server.
- */
- public String getContentType() {
- return this.resource.contentType;
- }
-
- /**
- * Return the last modified {@link Date} of the collection represented
- * by this {@link WebDavClient} as passed to us by the WebDAV server.
- */
- public Date getLastModified() {
- return this.resource.lastModified;
- }
-
- /**
- * Return the creation {@link Date} of the collection represented
- * by this {@link WebDavClient} as passed to us by the WebDAV server.
- */
- public Date getCreationDate() {
- return this.resource.creationDate;
- }
-
- /**
- * Return the {@link Location} associated with the specified child of
- * the collection represented by this {@link WebDavClient}.
- *
- * @throws IOException if the specified child does not exist.
- * @throws NullPointerException if the specified child was null.
- */
- public Location getLocation(String child)
- throws IOException {
- Location location = this.getResource(child).location;
- return this.resource.location.resolve(location);
- }
-
- /**
- * Checks if the specified child of the collection represented by this
- * {@link WebDavClient} instance is a collection.
- */
- public boolean isCollection(String child)
- throws IOException {
- return this.getResource(child).collection;
- }
-
- /**
- * Return the content length (in bytes) associated with the specified
- * child of the collection represented by this {@link WebDavClient}.
- *
- * @throws IOException if the specified child does not exist.
- * @throws NullPointerException if the specified child was null.
- */
- public long getContentLength(String child)
- throws IOException {
- return this.getResource(child).contentLength;
- }
-
- /**
- * Return the content type (mime-type) associated with the specified
- * child of the collection represented by this {@link WebDavClient}.
- *
- * @throws IOException if the specified child does not exist.
- * @throws NullPointerException if the specified child was null.
- */
- public String getContentType(String child)
- throws IOException {
- return this.getResource(child).contentType;
- }
-
- /**
- * Return the last modified {@link Date} associated with the specified
- * child of the collection represented by this {@link WebDavClient}.
- *
- * @throws IOException if the specified child does not exist.
- * @throws NullPointerException if the specified child was null.
- */
- public Date getLastModified(String child)
- throws IOException {
- return this.getResource(child).lastModified;
- }
-
- /**
- * Return the creation {@link Date} associated with the specified
- * child of the collection represented by this {@link WebDavClient}.
- *
- * @throws IOException if the specified child does not exist.
- * @throws NullPointerException if the specified child was null.
- */
- public Date getCreationDate(String child)
- throws IOException {
- return this.getResource(child).creationDate;
- }
-
- /* ====================================================================== */
- /* INTERNAL METHODS */
- /* ====================================================================== */
-
- /**
- * Return the resource associated with the specified child.
- *
- * @throws IOException if the specified child does not exist.
- * @throws NullPointerException if the specified child was null.
- */
- private Resource getResource(String child)
- throws IOException {
- if (child == null) throw new NullPointerException();
- final Resource resource = (Resource) this.children.get(child);
- if (resource == null) throw new IOException("Not found: " + child);
- return resource;
- }
-
- /**
- * Contact the remote WebDAV server and fetch all properties.
- */
- private void reload(Location location)
- throws IOException {
-
- /* Do an OPTIONS over onto the location */
- location = this.options(location);
-
- /* Do a PROPFIND to figure out the properties and the children */
- final Iterator iterator = this.propfind(location).iterator();
- final Map children = new HashMap();
- while (iterator.hasNext()) {
- final Resource resource = (Resource) iterator.next();
- final Path path = resource.location.getPath();
- if (path.size() == 0) {
- resource.location = location.resolve(resource.location);
- this.resource = resource;
- } else if (path.size() == 1) {
- final Path.Element element = (Path.Element) path.get(0);
- if ("..".equals(element.getName())) continue;
- children.put(element.toString(), resource);
- }
- }
-
- /* Check if the current resource was discovered */
- if (this.resource == null)
- throw new IOException("Current resource not returned in PROOPFIND");
-
- /* Don't actually allow resources to be modified */
- this.children = Collections.unmodifiableMap(children);
- }
-
- /**
- * Contact the remote WebDAV server and do an OPTIONS lookup.
- */
- private Location options(Location location)
- throws IOException {
- /* Create the new HttpClient instance associated with the location */
- final HttpClient client = new HttpClient(location);
- client.setAcceptableStatus(200).connect("OPTIONS", true).disconnect();
-
- /* Check that the remote server returned the "Dav" header */
- final List davHeader = client.getResponseHeaderValues("dav");
- if (davHeader == null) {
- throw new IOException("Server did not respond with a DAV header");
- }
-
- /* Check if the OPTIONS request contained the DAV header */
- final Iterator iterator = davHeader.iterator();
- boolean foundLevel1 = false;
- while (iterator.hasNext() && (! foundLevel1)) {
- String value = (String) iterator.next();
- StringTokenizer tokenizer = new StringTokenizer(value, ",");
- while (tokenizer.hasMoreTokens()) {
- if (! "1".equals(tokenizer.nextToken().trim())) continue;
- foundLevel1 = true;
- break;
- }
- }
-
- /* Return the (possibly redirected) location or fail miserably */
- if (foundLevel1) return client.getLocation();
- throw new IOException("Server doesn't support DAV Level 1");
- }
-
- /**
- * Contact the remote WebDAV server and do a PROPFIND lookup, returning
- * a {@link List} of all scavenged resources.
- */
- private List propfind(Location location)
- throws IOException {
- /* Create the new HttpClient instance associated with the location */
- final HttpClient client = new HttpClient(location);
- client.addRequestHeader("Depth", "1");
- client.setAcceptableStatus(207).connect("PROPFIND", true);
-
- /* Get the XML SAX Parser and parse the output of the PROPFIND */
- try {
- final SAXParserFactory factory = SAXParserFactory.newInstance();
- factory.setValidating(false);
- factory.setNamespaceAware(true);
- final SAXParser parser = factory.newSAXParser();
- final String systemId = location.toString();
- final InputSource source = new InputSource(systemId);
- final Handler handler = new Handler(location);
- source.setByteStream(client.getResponseStream());
- parser.parse(source, handler);
- return handler.list;
-
- } catch (ParserConfigurationException exception) {
- Exception throwable = new IOException("Error creating XML parser");
- throw (IOException) throwable.initCause(exception);
- } catch (SAXException exception) {
- Exception throwable = new IOException("Error creating XML parser");
- throw (IOException) throwable.initCause(exception);
- } finally {
- client.disconnect();
- }
- }
-
- /* ====================================================================== */
- /* INTERNAL CLASSES */
- /* ====================================================================== */
-
- /**
- * An internal XML {@link DefaultHandler} used to parse out the various
- * details of a PROPFIND response.
- */
- private static final class Handler extends DefaultHandler {
-
- /* ================================================================== */
- /* PSEUDO-XPATH LOCATIONS FOR QUICK-AND-DIRTY LOCATION LOOKUP */
- /* ================================================================== */
- private static final String RESPONSE_PATH = "/multistatus/response";
- private static final String HREF_PATH = "/multistatus/response/href";
- private static final String COLLECTION_PATH =
- "/multistatus/response/propstat/prop/resourcetype/collection";
- private static final String GETCONTENTTYPE_PATH =
- "/multistatus/response/propstat/prop/getcontenttype";
- private static final String GETLASTMODIFIED_PATH =
- "/multistatus/response/propstat/prop/getlastmodified";
- private static final String GETCONTENTLENGTH_PATH =
- "/multistatus/response/propstat/prop/getcontentlength";
- private static final String CREATIONDATE_PATH =
- "/multistatus/response/propstat/prop/creationdate";
-
- /** The {@link Location} for resolving all other links.
*/
- private final Location base;
- /** The {@link List} of all scavenged resources.
*/
- private final List list = new ArrayList();
- /** The resource currently being processed.
*/
- private Resource rsrc = null;
- /** A {@link StringBuffer} holding character data.
*/
- private StringBuffer buff = null;
- /** A {@link Stack} for quick-and-dirty pseudo XPath lookups.
*/
- private Stack stack = new Stack();
-
- /**
- * Create a new instance specifying the base {@link Location}.
- */
- private Handler(Location location) {
- this.base = location;
- }
-
- /**
- * Push an element name in the stack for pseudo-XPath lookups.
- *
- * @return a {@link String} like /element/element/element
.
- */
- private String pushPath(String path) {
- this.stack.push(path.toLowerCase());
- final StringBuffer buffer = new StringBuffer();
- for (int x = 0; x < this.stack.size(); x ++)
- buffer.append('/').append(this.stack.get(x));
- return buffer.toString();
- }
-
- /**
- * Pop the last element name from the pseudo-XPath lookup stack.
- *
- * @return a {@link String} like /element/element/element
.
- */
- private String popPath(String path)
- throws SAXException {
- final StringBuffer buffer = new StringBuffer();
- final String last = (String) this.stack.pop();
- if (path.toLowerCase().equals(last)) {
- for (int x = 0; x < this.stack.size(); x ++)
- buffer.append('/').append(this.stack.get(x));
- return buffer.append('/').append(last).toString();
- }
- throw new SAXException("Tag <" + path + "/> unbalanced at path \""
- + pushPath(last) + "\"");
- }
-
- /**
- * Handle the start-of-element SAX event.
- */
- public void startElement(String uri, String l, String q, Attributes a)
- throws SAXException {
- if (! "DAV:".equals(uri.toUpperCase())) return;
- final String path = this.pushPath(l);
-
- if (RESPONSE_PATH.equals(path)) {
- this.rsrc = new Resource();
-
- } else if (COLLECTION_PATH.equals(path)) {
- if (this.rsrc != null) this.rsrc.collection = true;
-
- } else if (GETCONTENTTYPE_PATH.equals(path) ||
- GETLASTMODIFIED_PATH.equals(path) ||
- GETCONTENTLENGTH_PATH.equals(path) ||
- CREATIONDATE_PATH.equals(path) ||
- HREF_PATH.equals(path)) {
- this.buff = new StringBuffer();
- }
- }
-
- /**
- * Handle the end-of-element SAX event.
- */
- public void endElement(String uri, String l, String q)
- throws SAXException {
- if (! "DAV:".equals(uri.toUpperCase())) return;
- final String path = this.popPath(l);
- final String data = this.resetBuffer();
-
- if (RESPONSE_PATH.equals(path)) {
- if (this.rsrc != null) {
- if (this.rsrc.location != null) {
- if (this.rsrc.location.isAbsolute()) {
- final String z = this.rsrc.location.toString();
- throw new SAXException("Unresolved location " + z);
- } else {
- this.list.add(this.rsrc);
- }
- } else {
- throw new SAXException("Null location for resource");
- }
- }
-
- } else if (HREF_PATH.equals(path)) {
- if (this.rsrc != null) try {
- final Location resolved = this.base.resolve(data);
- this.rsrc.location = this.base.relativize(resolved);
- if (! this.rsrc.location.isRelative())
- throw new SAXException("Unable to relativize location "
- + this.rsrc.location);
- } catch (MalformedURLException exception) {
- final String msg = "Unable to resolve URL \"" + data + "\"";
- SAXException throwable = new SAXException(msg, exception);
- throw (SAXException) throwable.initCause(exception);
- }
-
- } else if (CREATIONDATE_PATH.equals(path)) {
- if (this.rsrc != null)
- this.rsrc.creationDate = StringTools.parseIsoDate(data);
-
- } else if (GETCONTENTTYPE_PATH.equals(path)) {
- if (this.rsrc != null) this.rsrc.contentType = data;
-
- } else if (GETLASTMODIFIED_PATH.equals(path)) {
- if (this.rsrc != null)
- this.rsrc.lastModified = StringTools.parseHttpDate(data);
-
- } else if (GETCONTENTLENGTH_PATH.equals(path)) {
- if (this.rsrc != null) {
- Long length = StringTools.parseNumber(data);
- if (length != null) {
- this.rsrc.contentLength = length.longValue();
- }
- }
- }
- }
-
- /**
- * Handle SAX characters notification.
- */
- public void characters(char buffer[], int offset, int length) {
- if (this.buff != null) this.buff.append(buffer, offset, length);
- }
-
- /**
- * Reset the current characters buffer and return it as a
- * {@link String}.
- */
- private String resetBuffer() {
- if (this.buff == null) return null;
- if (this.buff.length() == 0) {
- this.buff = null;
- return null;
- }
- final String value = this.buff.toString();
- this.buff = null;
- return value;
- }
- }
-
- /**
- * A simple class holding the core resource properties.
- */
- private static class Resource {
- private Location location = null;
- private boolean collection = false;
- private long contentLength = -1;
- private String contentType = null;
- private Date lastModified = null;
- private Date creationDate = null;
- }
-
- /* ====================================================================== */
- /* COMMAND LINE CLIENT */
- /* ====================================================================== */
-
- /**
- * A command-line interface to a WebDAV repository.
- *
- * When invoked from the command line, this class requires one only
- * argument, the URL location of the WebDAV repository to connect to.
- *
- * After connection this method will interact with the user using an
- * extremely simple console-based interface.
- */
- public static void main(String args[])
- throws IOException {
- final InputStreamReader r = new InputStreamReader(System.in);
- final BufferedReader in = new BufferedReader(r);
- WebDavClient client = new WebDavClient(Location.parse(args[0]));
-
- while (true) try {
- System.out.print("[" + client.getLocation() + "] -> ");
- args = parse(in.readLine());
- if (args == null) break;
- if (args[0].equals("list")) {
- if (args[1] == null) list(client, System.out);
- else list(client.open(args[1]), System.out);
-
- } else if (args[0].equals("refresh")) {
- client = client.refresh();
-
- } else if (args[0].equals("get")) {
- if (args[1] != null) {
- final InputStream input = client.get(args[1]);
- final File file = new File(args[2]).getCanonicalFile();
- final OutputStream output = new FileOutputStream(file);
- final long bytes = StreamTools.copy(input, output);
- System.out.println("Fetched child \"" + args[1] +
- "\" to file \"" + file + "\" (" +
- bytes + " bytes)");
- }
- else System.out.print("Can't \"get\" null");
-
- } else if (args[0].equals("put")) {
- if (args[1] != null) {
- final File file = new File(args[1]).getCanonicalFile();
- final InputStream input = new FileInputStream(file);
- final OutputStream output = client.put(args[2], file.length());
- final long bytes = StreamTools.copy(input, output);
- System.out.println("Uploaded file \"" + file +
- "\" to child \"" + args[2] + "\" (" +
- bytes + " bytes)");
- }
- else System.out.print("Can't \"put\" null");
-
- } else if (args[0].equals("mkcol")) {
- if (args[1] != null) {
- client.mkcol(args[1]);
- System.out.println("Created \"" + args[1] + "\"");
- }
- else System.out.print("Can't \"mkcol\" null");
-
- } else if (args[0].equals("delete")) {
- if (args[1] != null) {
- client.delete(args[1]);
- System.out.println("Deleted \"" + args[1] + "\"");
- }
- else System.out.print("Can't \"delete\" null");
-
- } else if (args[0].equals("cd")) {
- if (args[1] != null) client = client.open(args[1]);
- else System.out.print("Can't \"cd\" to null");
-
- } else if (args[0].equals("quit")) {
- break;
-
- } else {
- System.out.print("Invalid command \"" + args[0] + "\". ");
- System.out.println("Valid commands are:");
- System.out.println(" - \"list\" list the children child");
- System.out.println(" - \"get\" fetch the specified child");
- System.out.println(" - \"put\" put the specified child");
- System.out.println(" - \"mkcol\" create a collection");
- System.out.println(" - \"delete\" delete a child");
- System.out.println(" - \"put\" put the specified resource");
- System.out.println(" - \"cd\" change the location");
- System.out.println(" - \"refresh\" refresh this location");
- System.out.println(" - \"quit\" quit this application");
- }
- } catch (Exception exception) {
- exception.printStackTrace(System.err);
- }
- System.err.println();
- }
-
- /**
- * Parse a line entered by the user returning a three-tokens argument
- * list (command, argument 1, argument 2)
- */
- private static String[] parse(String line) {
- if (line == null) return null;
- final String array[] = new String[3];
- final StringTokenizer tokenizer = new StringTokenizer(line);
- int offset = 0;
- while (tokenizer.hasMoreTokens() && (offset < 3))
- array[offset ++] = tokenizer.nextToken();
- if (array[0] == null) return null;
- if (array[2] == null) array[2] = array[1];
- return array;
- }
-
- /**
- * Pseudo-nicely display a list of the children of a collection
- */
- private static void list(WebDavClient client, PrintStream out)
- throws IOException {
- out.print("C | ");
- out.print("CONTENT TYPE | ");
- out.print("CREATED | ");
- out.print("MODIFIED | ");
- out.print("SIZE | ");
- out.println("NAME ");
- for (Iterator iterator = client.iterator(); iterator.hasNext() ; ) {
- final StringBuffer buffer = new StringBuffer();
- String child = (String) iterator.next();
- if (client.isCollection(child)) buffer.append("* | ");
- else buffer.append(" | ");
- format(buffer, client.getContentType(child), 15).append(" | ");
- format(buffer, client.getCreationDate(child), 19).append(" | ");
- format(buffer, client.getLastModified(child), 19).append(" | ");
- format(buffer, client.getContentLength(child), 10).append(" | ");
- out.println(buffer.append(child));
- }
- }
-
- /** Format a number aligning it to the right of a string.
*/
- private static StringBuffer format(StringBuffer buf, long num, int len) {
- final String data;
- if (num < 0) data = "";
- else data = Long.toString(num);
- final int spaces = len - data.length();
- for (int x = 0; x < spaces; x++) buf.append(' ');
- buf.append(data);
- return buf;
- }
-
- /** Format a string into an exact number of characters.
*/
- private static StringBuffer format(StringBuffer buf, Object obj, int len) {
- final String string;
- if (obj == null) {
- string = ("[null]");
- } else if (obj instanceof Date) {
- SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- string = f.format((Date) obj);
- } else {
- string = obj.toString();
- }
- final StringBuffer buffer = new StringBuffer(string);
- for (int x = string.length(); x < len; x ++) buffer.append(' ');
- return buf.append(buffer.substring(0, len));
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/http/package.html b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/http/package.html
deleted file mode 100644
index 9ca0cb4fa..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/http/package.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
- HTTP Utilities
-
-
-
- This package contains a number of utility classes to access
- HTTP and
- WebDAV servers.
-
-
-
\ No newline at end of file
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Location.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Location.java
deleted file mode 100644
index 24964795c..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Location.java
+++ /dev/null
@@ -1,805 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.util.location;
-
-import it.could.util.StringTools;
-import it.could.util.encoding.Encodable;
-import it.could.util.encoding.EncodingTools;
-
-import java.io.UnsupportedEncodingException;
-import java.net.MalformedURLException;
-import java.util.AbstractList;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-
-/**
- * An utility class representing an HTTP-like URL.
- *
- * This class can be used to represent any URL that roughly uses the HTTP
- * format. Compared to the standard {@link java.net.URL} class, the scheme part
- * of the a {@link Location} is never checked, and it's up to the application
- * to verify its correctness, while compared to the {@link java.net.URI} class,
- * its parsing mechanism is a lot more relaxed (be liberal in what you accept,
- * be strict in what you send).
- *
- * For a bigger picture on how this class works, this is an easy-to-read
- * representation of what the different parts of a {@link Location} are:
- *
- *
- *
- * One important difference between this implementation and the description
- * of URLs and
- * URIs is that parameter
- * paths are represented only at the end of the entire path structure
- * rather than for each path element. This over-simplification allows easy
- * relativization of {@link Location}s when used with servlet containers, which
- * normally use path parameters to encode the session id.
- *
- * @author Pier Fumagalli
- */
-public class Location implements Encodable {
-
- /** A {@link Map} of schemes and their default port number.
*/
- private static final Map schemePorts = new HashMap();
- static {
- schemePorts.put("acap", new Integer( 674));
- schemePorts.put("dav", new Integer( 80));
- schemePorts.put("ftp", new Integer( 21));
- schemePorts.put("gopher", new Integer( 70));
- schemePorts.put("http", new Integer( 80));
- schemePorts.put("https", new Integer( 443));
- schemePorts.put("imap", new Integer( 143));
- schemePorts.put("ldap", new Integer( 389));
- schemePorts.put("mailto", new Integer( 25));
- schemePorts.put("news", new Integer( 119));
- schemePorts.put("nntp", new Integer( 119));
- schemePorts.put("pop", new Integer( 110));
- schemePorts.put("rtsp", new Integer( 554));
- schemePorts.put("sip", new Integer(5060));
- schemePorts.put("sips", new Integer(5061));
- schemePorts.put("snmp", new Integer( 161));
- schemePorts.put("telnet", new Integer( 23));
- schemePorts.put("tftp", new Integer( 69));
- }
-
- /** The {@link List} of schemes of this {@link Location}.
*/
- private final Schemes schemes;
- /** The {@link Authority} of this {@link Location}.
*/
- private final Authority authority;
- /** The {@link Path} of this {@link Location}.
*/
- private final Path path;
- /** The {@link Parameters} of this {@link Location}.
*/
- private final Parameters parameters;
- /** The fragment part of this {@link Location}.
*/
- private final String fragment;
- /** The string representation of this {@link Location}.
*/
- private final String string;
-
- /**
- * Create a new {@link Location} instance.
- */
- public Location(Schemes schemes, Authority authority, Path path,
- Parameters parameters, String fragment)
- throws MalformedURLException {
- if ((schemes == null) && (authority != null))
- throw new MalformedURLException("No schemes specified");
- if ((schemes != null) && (authority == null))
- throw new MalformedURLException("No authority specified");
- if (path == null) throw new MalformedURLException("No path specified");
-
- this.schemes = schemes;
- this.authority = authority;
- this.path = path;
- this.parameters = parameters;
- this.fragment = fragment;
- this.string = EncodingTools.toString(this);
- }
-
- /* ====================================================================== */
- /* STATIC CONSTRUCTION METHODS */
- /* ====================================================================== */
-
- public static Location parse(String url)
- throws MalformedURLException {
- try {
- return parse(url, DEFAULT_ENCODING);
- } catch (UnsupportedEncodingException exception) {
- final String message = "Unsupported encoding " + DEFAULT_ENCODING;
- final InternalError error = new InternalError(message);
- throw (InternalError) error.initCause(exception);
- }
- }
-
- public static Location parse(String url, String encoding)
- throws MalformedURLException, UnsupportedEncodingException {
- if (url == null) return null;;
- if (encoding == null) encoding = DEFAULT_ENCODING;
- final String components[] = parseComponents(url);
- final Schemes schemes = parseSchemes(components[0], encoding);
- final int port = findPort(schemes, encoding);
- final Authority auth = parseAuthority(components[1], port, encoding);
- final Path path = Path.parse(components[2], encoding);
- final Parameters params = Parameters.parse(components[3], '&', encoding);
- final String fragment = components[4];
- return new Location(schemes, auth, path, params, fragment);
- }
-
- /* ====================================================================== */
- /* ACCESSOR METHODS */
- /* ====================================================================== */
-
- /**
- * Return an unmodifiable {@link Schemes list of all schemes} for this
- * {@link Location} instance or null.
- */
- public Schemes getSchemes() {
- return this.schemes;
- }
-
- /**
- * Return the {@link Location.Authority Authority} part for this
- * {@link Location} or null.
- */
- public Authority getAuthority() {
- return this.authority;
- }
-
- /**
- * Return the non-null {@link Path Path} structure
- * associated with this {@link Location} instance.
- */
- public Path getPath() {
- return this.path;
- }
-
- /**
- * Return an unmodifiable {@link Parameters list of all parameters}
- * parsed from this {@link Location}'s query string or null.
- */
- public Parameters getParameters() {
- return this.parameters;
- }
-
- /**
- * Return the fragment of this {@link Location} unencoded.
- */
- public String getFragment() {
- return this.fragment;
- }
-
- /* ====================================================================== */
- /* OBJECT METHODS */
- /* ====================================================================== */
-
- /**
- * Check if the specified {@link Object} is equal to this instance.
- *
- * The specified {@link Object} must be a non-null
- * {@link Location} instance whose {@link #toString() string value} equals
- * this one's.
- */
- public boolean equals(Object object) {
- if ((object != null) && (object instanceof Location)) {
- return this.string.equals(((Location)object).string);
- } else {
- return false;
- }
- }
-
- /**
- * Return the hash code value for this {@link Location} instance.
- */
- public int hashCode() {
- return this.string.hashCode();
- }
-
- /**
- * Return the {@link String} representation of this {@link Location}
- * instance.
- */
- public String toString() {
- return this.string;
- }
-
- /**
- * Return the {@link String} representation of this {@link Location}
- * instance using the specified character encoding.
- */
- public String toString(String encoding)
- throws UnsupportedEncodingException {
- final StringBuffer buffer = new StringBuffer();
-
- /* Render the schemes */
- if (this.schemes != null)
- buffer.append(this.schemes.toString(encoding)).append("://");
-
- /* Render the authority part */
- if (this.authority != null)
- buffer.append(this.authority.toString(encoding));
-
- /* Render the paths */
- buffer.append(this.path.toString(encoding));
-
- /* Render the query string */
- if (this.parameters != null)
- buffer.append('?').append(this.parameters.toString(encoding));
-
- /* Render the fragment */
- if (this.fragment != null) {
- buffer.append('#');
- buffer.append(EncodingTools.urlEncode(this.fragment, encoding));
- }
-
- /* Return the string */
- return buffer.toString();
- }
-
- /* ====================================================================== */
- /* PUBLIC METHODS */
- /* ====================================================================== */
-
- /**
- * Checks whether this {@link Location} is absolute or not.
- *
- * This method must not be confused with the similarly named
- * {@link Path#isAbsolute() Path.isAbsolute()} method.
- * This method will check whether the full {@link Location} is absolute (it
- * has a scheme), while the one exposed by the {@link Path Path}
- * class will check if the path is absolute.
- */
- public boolean isAbsolute() {
- return this.schemes != null && this.authority != null;
- }
-
- public boolean isRelative() {
- return ! (this.isAbsolute() || this.path.isAbsolute());
- }
-
- public boolean isAuthoritative(Location location) {
- if (! this.isAbsolute()) return false;
- if (! location.isAbsolute()) return true;
- return this.schemes.equals(location.schemes) &&
- this.authority.equals(location.authority);
- }
-
- /* ====================================================================== */
- /* RESOLUTION METHODS */
- /* ====================================================================== */
-
- public Location resolve(String url)
- throws MalformedURLException {
- try {
- return this.resolve(parse(url, DEFAULT_ENCODING));
- } catch (UnsupportedEncodingException exception) {
- final String message = "Unsupported encoding " + DEFAULT_ENCODING;
- final InternalError error = new InternalError(message);
- throw (InternalError) error.initCause(exception);
- }
- }
-
- public Location resolve(String url, String encoding)
- throws MalformedURLException, UnsupportedEncodingException {
- if (encoding == null) encoding = DEFAULT_ENCODING;
- return this.resolve(parse(url, encoding));
- }
-
- public Location resolve(Location location) {
- if (! this.isAuthoritative(location)) return location;
-
- /* Schemes are the same */
- final Schemes schemes = this.schemes;
-
- /* Authority needs to be merged (for username and password) */
- final Authority auth;
- if (location.authority != null) {
- final String username = location.authority.username != null ?
- location.authority.username :
- this.authority.username;
- final String password = location.authority.password != null ?
- location.authority.password :
- this.authority.password;
- final String host = location.authority.host;
- final int port = location.authority.port;
- auth = new Authority(username, password, host, port);
- } else {
- auth = this.authority;
- }
-
- /* Path can be resolved */
- final Path path = this.path.resolve(location.path);
-
- /* Parametrs and fragment are the ones of the target */
- final Parameters params = location.parameters;
- final String fragment = location.fragment;
-
- /* Create a new {@link Location} instance */
- try {
- return new Location(schemes, auth, path, params, fragment);
- } catch (MalformedURLException exception) {
- /* Should really never happen */
- Error error = new InternalError("Can't instantiate Location");
- throw (Error) error.initCause(exception);
- }
- }
-
- /* ====================================================================== */
- /* RELATIVIZATION METHODS */
- /* ====================================================================== */
-
- public Location relativize(String url)
- throws MalformedURLException {
- try {
- return this.relativize(parse(url, DEFAULT_ENCODING));
- } catch (UnsupportedEncodingException exception) {
- final String message = "Unsupported encoding " + DEFAULT_ENCODING;
- final InternalError error = new InternalError(message);
- throw (InternalError) error.initCause(exception);
- }
- }
-
- public Location relativize(String url, String encoding)
- throws MalformedURLException, UnsupportedEncodingException {
- if (encoding == null) encoding = DEFAULT_ENCODING;
- return this.relativize(parse(url, encoding));
- }
-
- public Location relativize(Location location) {
- final Path path;
- if (!location.isAbsolute()) {
- /* Target location is not absolute, its path might */
- path = this.path.relativize(location.path);
- } else {
- if (this.isAuthoritative(location)) {
- /* Target location is not on the same authority, process path */
- path = this.path.relativize(location.path);
- } else {
- /* Not authoritative for a non-relative location, yah! */
- return location;
- }
- }
- try {
- return new Location(null, null, path, location.parameters,
- location.fragment);
- } catch (MalformedURLException exception) {
- /* Should really never happen */
- Error error = new InternalError("Can't instantiate Location");
- throw (Error) error.initCause(exception);
- }
- }
-
- /* ====================================================================== */
- /* INTERNAL PARSING ROUTINES */
- /* ====================================================================== */
-
- /**
- * Return the port number associated with the specified schemes.
- */
- public static int findPort(List schemes, String encoding)
- throws UnsupportedEncodingException {
- if (schemes == null) return -1;
- if (schemes.size() < 1) return -1;
- Integer p = (Integer) schemePorts.get(schemes.get(schemes.size() - 1));
- return p == null ? -1 : p.intValue();
- }
-
- /**
- * Parse scheme://authority/path?query#fragment
.
- *
- * @return an array of five {@link String}s: scheme (0), authority (1),
- * path (2), query (3) and fragment (4).
- */
- private static String[] parseComponents(String url)
- throws MalformedURLException {
- /* Scheme, easy and simple */
- final String scheme;
- final String afterScheme;
- final int schemeEnd = url.indexOf(":/");
- if (schemeEnd > 0) {
- scheme = url.substring(0, schemeEnd).toLowerCase();
- afterScheme = url.substring(schemeEnd + 2);
- } else if (schemeEnd == 0) {
- throw new MalformedURLException("Missing scheme");
- } else {
- scheme = null;
- afterScheme = url;
- }
-
- /* Authority (can be tricky because it can be emtpy) */
- final String auth;
- final String afterAuth;
- if (scheme == null) {
- // --> /path... or path...
- afterAuth = afterScheme;
- auth = null;
- } else if (afterScheme.length() > 0 && afterScheme.charAt(0) == '/') {
- // --> scheme://...
- final int pathStart = afterScheme.indexOf('/', 1);
- if (pathStart == 1) {
- // --> scheme:///path...
- afterAuth = afterScheme.substring(pathStart);
- auth = null;
- } else if (pathStart > 1) {
- // --> scheme://authority/path...
- afterAuth = afterScheme.substring(pathStart);
- auth = afterScheme.substring(1, pathStart);
- } else {
- // --> scheme://authority (but no slashes for the path)
- final int authEnds = StringTools.findFirst(afterScheme, "?#");
- if (authEnds < 0) {
- // --> scheme://authority (that's it, return)
- auth = afterScheme.substring(1);
- return new String[] { scheme, auth, "/", null, null };
- }
- // --> scheme://authority?... or scheme://authority#...
- auth = afterScheme.substring(1, authEnds);
- afterAuth = "/" + afterScheme.substring(authEnds);
- }
- } else {
- // --> scheme:/path...
- afterAuth = url.substring(schemeEnd + 1);
- auth = null;
- }
-
- /* Path, can be terminated by '?' or '#' whichever is first */
- final int pathEnds = StringTools.findFirst(afterAuth, "?#");
- if (pathEnds < 0) {
- // --> ...path... (no fragment or query, return now)
- return new String[] { scheme, auth, afterAuth, null, null };
- }
-
- /* We have either a query, a fragment or both after the path */
- final String path = afterAuth.substring(0, pathEnds);
- final String afterPath = afterAuth.substring(pathEnds + 1);
-
- /* Query? The query can contain a "#" and has an extra fragment */
- if (afterAuth.charAt(pathEnds) == '?') {
- final int fragmPos = afterPath.indexOf('#');
- if (fragmPos < 0) {
- // --> ...path...?... (no fragment)
- return new String[] { scheme, auth, path, afterPath, null };
- }
-
- // --> ...path...?...#... (has also a fragment)
- final String query = afterPath.substring(1, fragmPos);
- final String fragm = afterPath.substring(fragmPos + 1);
- return new String[] { scheme, auth, path, query, fragm };
- }
-
- // --> ...path...#... (a path followed by a fragment but no query)
- return new String[] { scheme, auth, path, null, afterPath };
- }
-
- /**
- * Parse scheme:scheme:scheme...
.
- */
- private static Schemes parseSchemes(String scheme, String encoding)
- throws MalformedURLException, UnsupportedEncodingException {
- if (scheme == null) return null;
- final String split[] = StringTools.splitAll(scheme, ':');
- List list = new ArrayList();
- for (int x = 0; x < split.length; x++) {
- if (split[x] == null) continue;
- list.add(EncodingTools.urlDecode(split[x], encoding));
- }
- if (list.size() != 0) return new Schemes(list);
- throw new MalformedURLException("Empty scheme detected");
- }
-
- /**
- * Parse username:password@hostname:port
.
- */
- private static Authority parseAuthority(String auth, int defaultPort,
- String encoding)
- throws MalformedURLException, UnsupportedEncodingException {
- if (auth == null) return null;
- final String split[] = StringTools.splitOnce(auth, '@', true);
- final String uinfo[] = StringTools.splitOnce(split[0], ':', false);
- final String hinfo[] = StringTools.splitOnce(split[1], ':', false);
- final int port;
-
- if ((split[0] != null) && (split[1] == null))
- throw new MalformedURLException("Missing required host info part");
- if ((uinfo[0] == null) && (uinfo[1] != null))
- throw new MalformedURLException("Password specified without user");
- if ((hinfo[0] == null) && (hinfo[1] != null))
- throw new MalformedURLException("Port specified without host");
- try {
- if (hinfo[1] != null) {
- final int parsedPort = Integer.parseInt(hinfo[1]);
- if ((parsedPort < 1) || (parsedPort > 65535)) {
- final String message = "Invalid port number " + parsedPort;
- throw new MalformedURLException(message);
- }
- /* If the specified port is the default one, ignore it! */
- if (defaultPort == parsedPort) port = -1;
- else port = parsedPort;
- } else {
- port = -1;
- }
- } catch (NumberFormatException exception) {
- throw new MalformedURLException("Specified port is not a number");
- }
- return new Authority(EncodingTools.urlDecode(uinfo[0], encoding),
- EncodingTools.urlDecode(uinfo[1], encoding),
- EncodingTools.urlDecode(hinfo[0], encoding),
- port);
- }
-
- /* ====================================================================== */
- /* PUBLIC INNER CLASSES */
- /* ====================================================================== */
-
- /**
- * The {@link Location.Schemes Schemes} class represents an unmodifiable
- * ordered collection of {@link String} schemes for a {@link Location}.
- *
- * @author Pier Fumagalli
- */
- public static class Schemes extends AbstractList implements Encodable {
- /** All the {@link String} schemes in order.
*/
- private final String schemes[];
- /** The {@link String} representation of this instance.
*/
- private final String string;
-
- /**
- * Create a new {@link Schemes} instance.
- */
- private Schemes(List schemes) {
- final int size = schemes.size();
- this.schemes = (String []) schemes.toArray(new String[size]);
- this.string = EncodingTools.toString(this);
- }
-
- /**
- * Return the {@link String} scheme at the specified index.
- */
- public Object get(int index) {
- return this.schemes[index];
- }
-
- /**
- * Return the number of {@link String} schemes contained by this
- * {@link Location.Schemes Schemes} instance.
- */
- public int size() {
- return this.schemes.length;
- }
-
- /**
- * Return the URL-encoded {@link String} representation of this
- * {@link Location.Schemes Schemes} instance.
- */
- public String toString() {
- return this.string;
- }
-
- /**
- * Return the URL-encoded {@link String} representation of this
- * {@link Location.Schemes Schemes} instance using the specified
- * character encoding.
- */
- public String toString(String encoding)
- throws UnsupportedEncodingException {
- final StringBuffer buffer = new StringBuffer();
- for (int x = 0; x < this.schemes.length; x ++) {
- buffer.append(':');
- buffer.append(EncodingTools.urlEncode(this.schemes[x], encoding));
- }
- return buffer.substring(1);
- }
-
- /**
- * Return the hash code value for this
- * {@link Location.Schemes Schemes} instance.
- */
- public int hashCode() {
- return this.string.hashCode();
- }
-
- /**
- * Check if the specified {@link Object} is equal to this
- * {@link Location.Schemes Schemes} instance.
- *
- * The specified {@link Object} is considered equal to this one if
- * it is non-null, it is a {@link Location.Schemes Schemes}
- * instance, and its {@link #toString() string representation} equals
- * this one's.
- */
- public boolean equals(Object object) {
- if ((object != null) && (object instanceof Schemes)) {
- return this.string.equals(((Schemes) object).string);
- } else {
- return false;
- }
- }
- }
-
- /* ====================================================================== */
-
- /**
- * The {@link Location.Authority Authority} class represents the autority
- * and user information for a {@link Location}.
- *
- * @author Pier Fumagalli
- */
- public static class Authority implements Encodable {
- /** The username of this instance (decoded).
*/
- private final String username;
- /** The password of this instance (decoded).
*/
- private final String password;
- /** The host name of this instance (decoded).
*/
- private final String host;
- /** The port number of this instance.
*/
- private final int port;
- /** The encoded host and port representation.
*/
- private final String hostinfo;
- /** The encoded string representation of this instance.
*/
- private final String string;
-
- /**
- * Create a new {@link Location.Authority Authority} instance.
- */
- private Authority(String user, String pass, String host, int port) {
- this.username = user;
- this.password = pass;
- this.host = host;
- this.port = port;
- try {
- this.hostinfo = this.getHostInfo(DEFAULT_ENCODING);
- this.string = this.toString(DEFAULT_ENCODING);
- } catch (UnsupportedEncodingException exception) {
- final String message = "Default encoding \"" + DEFAULT_ENCODING
- + "\" not supported by the platform";
- final InternalError error = new InternalError(message);
- throw (InternalError) error.initCause(exception);
- }
- }
-
- /**
- * Returns the decoded user name.
- */
- public String getUsername() {
- return this.username;
- }
-
- /**
- * Returns the decoded password.
- */
- public String getPassword() {
- return this.password;
- }
-
- /**
- * Returns the "user info" field.
- *
- * This method will concatenate the username and password using the
- * colon character and return a non-null {@link String} only if
- * both of them are non-null.
- */
- public String getUserInfo() {
- if ((this.username == null) || (this.password == null)) return null;
- return this.username + ':' + this.password;
- }
-
- /**
- * Returns the decoded host name.
- */
- public String getHost() {
- return this.host;
- }
-
- /**
- * Returns the port number.
- */
- public int getPort() {
- return this.port;
- }
-
- /**
- * Returns the host info part of the
- * {@link Location.Authority Authority}.
- *
- * This is the encoded representation of the
- * {@link #getUsername() user name} optionally follwed by the colon (:)
- * character and the encoded {@link #getPassword() password}.
- */
- public String getHostInfo() {
- return this.hostinfo;
- }
-
- /**
- * Returns the host info part of the
- * {@link Location.Authority Authority} using the specified character
- * encoding.
- *
- * This is the encoded representation of the
- * {@link #getUsername() user name} optionally follwed by the colon (:)
- * character and the encoded {@link #getPassword() password}.
- */
- public String getHostInfo(String encoding)
- throws UnsupportedEncodingException {
- final StringBuffer hostinfo = new StringBuffer();
- hostinfo.append(EncodingTools.urlEncode(this.host, encoding));
- if (port >= 0) hostinfo.append(':').append(port);
- return hostinfo.toString();
- }
-
- /**
- * Return the URL-encoded {@link String} representation of this
- * {@link Location.Authority Authority} instance.
- */
- public String toString() {
- return this.string;
- }
-
- /**
- * Return the URL-encoded {@link String} representation of this
- * {@link Location.Authority Authority} instance using the specified
- * character encoding.
- */
- public String toString(String encoding)
- throws UnsupportedEncodingException {
- final StringBuffer buffer;
- if (this.username != null) {
- buffer = new StringBuffer();
- buffer.append(EncodingTools.urlEncode(this.username, encoding));
- if (this.password != null) {
- buffer.append(':');
- buffer.append(EncodingTools.urlEncode(this.password, encoding));
- }
- } else {
- buffer = null;
- }
-
- if (buffer == null) return this.getHostInfo(encoding);
- buffer.append('@').append(this.getHostInfo(encoding));
- return buffer.toString();
- }
-
- /**
- * Return the hash code value for this
- * {@link Location.Authority Authority} instance.
- */
- public int hashCode() {
- return this.hostinfo.hashCode();
- }
-
- /**
- * Check if the specified {@link Object} is equal to this
- * {@link Location.Authority Authority} instance.
- *
- * The specified {@link Object} is considered equal to this one if
- * it is non-null, it is a {@link Location.Authority Authority}
- * instance, and its {@link #getHostInfo() host info} equals
- * this one's.
- */
- public boolean equals(Object object) {
- if ((object != null) && (object instanceof Authority)) {
- return this.hostinfo.equals(((Authority) object).hostinfo);
- } else {
- return false;
- }
- }
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Parameters.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Parameters.java
deleted file mode 100644
index 3ffa0bac7..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Parameters.java
+++ /dev/null
@@ -1,474 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.util.location;
-
-import it.could.util.StringTools;
-import it.could.util.encoding.Encodable;
-import it.could.util.encoding.EncodingTools;
-
-import java.io.UnsupportedEncodingException;
-import java.util.AbstractList;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-
-/**
- * The {@link Parameters Parameters} class represents a never empty and
- * immutable {@link List} of {@link Parameters.Parameter Parameter} instances,
- * normally created parsing a query string.
- *
- * @author Pier Fumagalli
- */
-public class Parameters extends AbstractList implements Encodable {
-
- /** The default delimiter for a {@link Parameters} instance.
*/
- public static final char DEFAULT_DELIMITER = '&';
-
- /** All the {@link Parameter}s in order.
*/
- private final Parameter parameters[];
- /** The {@link Map} view over all parameters (names are keys).
*/
- private final Map map;
- /** The {@link Set} of all parameter names.
*/
- final Set names;
- /** The character delimiting different parameters.
*/
- private final char delimiter;
- /** The encoded {@link String} representation of this.
*/
- private final String string;
-
- /**
- * Create a new {@link Parameters Parameters} instance from
- * a {@link List} of {@link Parameters.Parameter Parameter} instances
- * using the {@link #DEFAULT_DELIMITER default parameter delimiter}.
- *
- * @throws NullPointerExceptoin if the {@link List} was null.
- * @throws IllegalArgumentException if the {@link List} was empty.
- * @throws ClassCastException if any of the elements in the {@link List} was
- * not a {@link Parameters.Parameter Parameter}.
- */
- public Parameters(List parameters) {
- this(parameters, DEFAULT_DELIMITER);
- }
-
- /**
- * Create a new {@link Parameters Parameters} instance from
- * a {@link List} of {@link Parameters.Parameter Parameter} instances
- * using the specified character as the parameters delimiter.
- *
- * @throws NullPointerExceptoin if the {@link List} was null.
- * @throws IllegalArgumentException if the {@link List} was empty.
- * @throws ClassCastException if any of the elements in the {@link List} was
- * not a {@link Parameters.Parameter Parameter}.
- */
- public Parameters(List parameters, char delimiter) {
- if (parameters.size() == 0) throw new IllegalArgumentException();
- final Parameter array[] = new Parameter[parameters.size()];
- final Map map = new HashMap();
- for (int x = 0; x < array.length; x ++) {
- final Parameter parameter = (Parameter) parameters.get(x);
- final String key = parameter.getName();
- List values = (List) map.get(key);
- if (values == null) {
- values = new ArrayList();
- map.put(key, values);
- }
- values.add(parameter.getValue());
- array[x] = parameter;
- }
-
- /* Make all parameter value lists unmodifiable */
- for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); ) {
- final Map.Entry entry = (Map.Entry) iter.next();
- final List list = (List) entry.getValue();
- entry.setValue(Collections.unmodifiableList(list));
- }
-
- /* Store the current values */
- this.delimiter = delimiter;
- this.map = Collections.unmodifiableMap(map);
- this.names = Collections.unmodifiableSet(map.keySet());
- this.parameters = array;
- this.string = EncodingTools.toString(this);
- }
-
- /* ====================================================================== */
- /* STATIC CONSTRUCTION METHODS */
- /* ====================================================================== */
-
- /**
- * Utility method to create a new {@link Parameters} instance from a
- * {@link List} of {@link Parameters.Parameter Parameter} instances.
- *
- * @return a non-null and not empty {@link Parameters} instance or
- * null if the specified {@link List} was null, empty
- * or did not contain any {@link Parameters.Parameter Parameter}.
- * @throws ClassCastException if any of the elements in the {@link List} was
- * not a {@link Parameters.Parameter Parameter}.
- */
- public static Parameters create(List parameters) {
- return create(parameters, DEFAULT_DELIMITER);
- }
-
- /**
- * Utility method to create a new {@link Parameters} instance from a
- * {@link List} of {@link Parameters.Parameter Parameter} instances.
- *
- * @return a non-null and not empty {@link Parameters} instance or
- * null if the specified {@link List} was null, empty
- * or did not contain any {@link Parameters.Parameter Parameter}.
- * @throws ClassCastException if any of the elements in the {@link List} was
- * not a {@link Parameters.Parameter Parameter}.
- */
- public static Parameters create(List parameters, char delimiter) {
- if (parameters == null) return null;
- final List dedupes = new ArrayList();
- for (Iterator iter = parameters.iterator(); iter.hasNext(); ) {
- Object next = iter.next();
- if (dedupes.contains(next)) continue;
- dedupes.add(next);
- }
- if (dedupes.size() == 0) return null;
- return new Parameters(dedupes, delimiter);
- }
-
- /**
- * Parse the specified parameters {@link String} into a
- * {@link Parameters} instance using the {@link #DEFAULT_DELIMITER default
- * parameter delimiter}.
- *
- * @return a non-null and not empty {@link Parameters} instance or
- * null if the specified string was null, empty or
- * did not contain any {@link Parameters.Parameter Parameter}.
- */
- public static Parameters parse(String parameters) {
- try {
- return parse(parameters, DEFAULT_DELIMITER, DEFAULT_ENCODING);
- } catch (UnsupportedEncodingException exception) {
- final String message = "Unsupported encoding " + DEFAULT_ENCODING;
- final InternalError error = new InternalError(message);
- throw (InternalError) error.initCause(exception);
- }
- }
-
- /**
- * Parse the specified parameters {@link String} into a
- * {@link Parameters} instance using the specified character as the
- * parameters delimiter.
- *
- * @return a non-null and not empty {@link Parameters} instance or
- * null if the specified string was null, empty or
- * did not contain any {@link Parameters.Parameter Parameter}.
- */
- public static Parameters parse(String parameters, char delimiter) {
- try {
- return parse(parameters, delimiter, DEFAULT_ENCODING);
- } catch (UnsupportedEncodingException exception) {
- final String message = "Unsupported encoding " + DEFAULT_ENCODING;
- final InternalError error = new InternalError(message);
- throw (InternalError) error.initCause(exception);
- }
- }
-
- /**
- * Parse the specified parameters {@link String} into a
- * {@link Parameters} instance using the {@link #DEFAULT_DELIMITER default
- * parameter delimiter}.
- *
- * @return a non-null and not empty {@link Parameters} instance or
- * null if the specified string was null, empty or
- * did not contain any {@link Parameters.Parameter Parameter}.
- */
- public static Parameters parse(String parameters, String encoding)
- throws UnsupportedEncodingException {
- return parse(parameters, DEFAULT_DELIMITER, encoding);
- }
-
- /**
- * Parse the specified parameters {@link String} into a
- * {@link Parameters} instance using the specified character as the
- * parameters delimiter.
- *
- * @return a non-null and not empty {@link Parameters} instance or
- * null if the specified string was null, empty or
- * did not contain any {@link Parameters.Parameter Parameter}.
- */
- public static Parameters parse(String parameters, char delimiter,
- String encoding)
- throws UnsupportedEncodingException {
- if (parameters == null) return null;
- if (parameters.length() == 0) return null;
- if (encoding == null) encoding = DEFAULT_ENCODING;
- final String split[] = StringTools.splitAll(parameters, delimiter);
- final List list = new ArrayList();
- for (int x = 0; x < split.length; x ++) {
- if (split[x] == null) continue;
- if (split[x].length() == 0) continue;
- Parameter parameter = Parameter.parse(split[x], encoding);
- if (parameter != null) list.add(parameter);
- }
- if (list.size() == 0) return null;
- return new Parameters(list, delimiter);
- }
-
- /* ====================================================================== */
- /* PUBLIC EXPOSED METHODS */
- /* ====================================================================== */
-
- /**
- * Return the number of {@link Parameters.Parameter Parameter}s
- * contained by this instance.
- */
- public int size() {
- return this.parameters.length;
- }
-
- /**
- * Return the {@link Parameters.Parameter Parameter} stored by this\
- * instance at the specified index.
- */
- public Object get(int index) {
- return this.parameters[index];
- }
-
- /**
- * Return an immutable {@link Set} of {@link String}s containing all
- * known {@link Parameters.Parameter Parameter}
- * {@link Parameters.Parameter#getName() names}.
- */
- public Set getNames() {
- return this.names;
- }
-
- /**
- * Return the first {@link String} value associated with the
- * specified parameter name, or null.
- */
- public String getValue(String name) {
- final List values = (List) this.map.get(name);
- return values == null ? null : (String) values.get(0);
- }
-
- /**
- * Return an immutable {@link List} of all {@link String} values
- * associated with the specified parameter name, or null.
- */
- public List getValues(String name) {
- return (List) this.map.get(name);
- }
-
- /* ====================================================================== */
- /* OBJECT METHODS */
- /* ====================================================================== */
-
- /**
- * Return the URL-encoded {@link String} representation of this
- * {@link Parameters Parameters} instance.
- */
- public String toString() {
- return this.string;
- }
-
- /**
- * Return the URL-encoded {@link String} representation of this
- * {@link Parameters Parameters} instance using the specified
- * character encoding.
- */
- public String toString(String encoding)
- throws UnsupportedEncodingException {
- StringBuffer buffer = new StringBuffer();
- for (int x = 0; x < this.parameters.length; x ++) {
- buffer.append(this.delimiter);
- buffer.append(this.parameters[x].toString(encoding));
- }
- return buffer.substring(1);
- }
-
- /**
- * Return the hash code value of this
- * {@link Parameters Parameters} instance.
- */
- public int hashCode() {
- return this.string.hashCode();
- }
-
- /**
- * Check if the specified {@link Object} is equal to this
- * {@link Parameters Parameters} instance.
- *
- * The specified {@link Object} is considered equal to this one if
- * it is non-null, it is a {@link Parameters Parameters}
- * instance, and its {@link #toString() string representation} equals
- * this one's.
- */
- public boolean equals(Object object) {
- if ((object != null) && (object instanceof Parameters)) {
- return this.string.equals(((Parameters) object).string);
- } else {
- return false;
- }
- }
-
- /* ====================================================================== */
- /* PUBLIC INNER CLASSES */
- /* ====================================================================== */
-
- /**
- * The {@link Parameters.Parameter Parameter} class represents a single
- * parameter either parsed from a query string or a path element.
- *
- * @author Pier Fumagalli
- */
- public static class Parameter implements Encodable {
- /** The name of the parameter (decoded).
*/
- private final String name;
- /** The value of the parameter (decoded).
*/
- private final String value;
- /** The encoded {@link String} representation of this.
*/
- private final String string;
-
- /**
- * Create a new {@link Parameters.Parameter Parameter} given an
- * encoded parameter name and value.
- *
- * @throws NullPointerException if the name was null.
- * @throws IllegalArgumentException if the name was an empty string.
- */
- public Parameter(String name, String value) {
- if (name == null) throw new NullPointerException();
- if (name.length() == 0) throw new IllegalArgumentException();
- this.name = name;
- this.value = value;
- this.string = EncodingTools.toString(this);
- }
-
- /* ================================================================== */
- /* STATIC CONSTRUCTION METHODS */
- /* ================================================================== */
-
- /**
- * Parse the specified parameters {@link String} into a
- * {@link Parameters.Parameter} instance.
- *
- * @return a non-null and not empty {@link Parameters.Parameter}
- * instance or null if the specified string was
- * null or empty.
- */
- public static Parameter parse(String parameter)
- throws UnsupportedEncodingException {
- try {
- return parse(parameter, DEFAULT_ENCODING);
- } catch (UnsupportedEncodingException exception) {
- final String message = "Unsupported encoding " + DEFAULT_ENCODING;
- final InternalError error = new InternalError(message);
- throw (InternalError) error.initCause(exception);
- }
- }
-
- /**
- * Parse the specified parameters {@link String} into a
- * {@link Parameters.Parameter} instance.
- *
- * @return a non-null and not empty {@link Parameters.Parameter}
- * instance or null if the specified string was
- * null or empty.
- */
- public static Parameter parse(String parameter, String encoding)
- throws UnsupportedEncodingException {
- if (parameter == null) return null;
- if (encoding == null) encoding = DEFAULT_ENCODING;
- String split[] = StringTools.splitOnce(parameter, '=', false);
- if (split[0] == null) return null;
- return new Parameter(split[0], split[1]);
- }
-
- /* ================================================================== */
- /* PUBLIC EXPOSED METHODS */
- /* ================================================================== */
-
- /**
- * Return the URL-decoded name of this
- * {@link Parameters.Parameter Parameter} instance.
- */
- public String getName() {
- return this.name;
- }
-
- /**
- * Return the URL-decoded value of this
- * {@link Parameters.Parameter Parameter} instance.
- */
- public String getValue() {
- return this.value;
- }
-
- /* ================================================================== */
- /* OBJECT METHODS */
- /* ================================================================== */
-
- /**
- * Return the URL-encoded {@link String} representation of this
- * {@link Parameters.Parameter Parameter} instance.
- */
- public String toString() {
- return this.string;
- }
-
- /**
- * Return the URL-encoded {@link String} representation of this
- * {@link Parameters.Parameter Parameter} instance using the specified
- * character encoding.
- */
- public String toString(String encoding)
- throws UnsupportedEncodingException {
- if (this.value != null) {
- return EncodingTools.urlEncode(this.name, encoding) + "=" +
- EncodingTools.urlEncode(this.value, encoding);
- } else {
- return EncodingTools.urlEncode(this.name, encoding);
- }
- }
-
- /**
- * Return the hash code value for this
- * {@link Parameters.Parameter Parameter} instance.
- */
- public int hashCode() {
- return this.string.hashCode();
- }
-
- /**
- * Check if the specified {@link Object} is equal to this
- * {@link Parameters.Parameter Parameter} instance.
- *
- * The specified {@link Object} is considered equal to this one if
- * it is non-null, it is a {@link Parameters.Parameter Parameter}
- * instance, and its {@link #toString() string representation} equals
- * this one's.
- */
- public boolean equals(Object object) {
- if ((object != null) && (object instanceof Parameter)) {
- return this.string.equals(((Parameter) object).string);
- } else {
- return false;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Path.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Path.java
deleted file mode 100644
index 722a0d46b..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Path.java
+++ /dev/null
@@ -1,559 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.util.location;
-
-import it.could.util.StringTools;
-import it.could.util.encoding.Encodable;
-import it.could.util.encoding.EncodingTools;
-
-import java.io.UnsupportedEncodingException;
-import java.util.AbstractList;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Stack;
-
-
-/**
- * The {@link Path Path} class is an ordered collection of
- * {@link Path.Element Element} instances representing a path
- * structure.
- *
- * @author Pier Fumagalli
- */
-public class Path extends AbstractList implements Encodable {
-
- /** The array of {@link Path.Element Element}s.
*/
- private final Element paths[];
- /** The current {@link Parameters} instance or null.
*/
- private final Parameters parameters;
- /** A flag indicating whether this path is absolute or not.
*/
- private final boolean absolute;
- /** A flag indicating if this path is a collection or not.
*/
- private final boolean collection;
- /** The {@link String} representation of this (encoded).
*/
- private final String string;
-
- /**
- * Create a new {@link Path Path} instance.
- *
- * @throws ClassCastException if any of the elements in the {@link List}
- * was not a {@link Path.Element Element}.
- */
- public Path(List elements, boolean absolute, boolean collection) {
- this(elements, absolute, collection, null);
- }
-
- /**
- * Create a new {@link Path Path} instance.
- *
- * @throws ClassCastException if any of the elements in the {@link List}
- * was not a {@link Path.Element Element}.
- */
- public Path(List elements, boolean absolute, boolean collection,
- Parameters parameters) {
- final Stack resolved = resolve(null, absolute, elements);
- final Element array[] = new Element[resolved.size()];
- this.paths = (Element []) resolved.toArray(array);
- this.parameters = parameters;
- this.absolute = absolute;
- this.collection = collection;
- this.string = EncodingTools.toString(this);
- }
-
- /* ====================================================================== */
- /* STATIC CONSTRUCTION METHODS */
- /* ====================================================================== */
-
- /**
- * Parse the specified {@link String} into a {@link Path} structure.
- */
- public static Path parse(String path) {
- try {
- return parse(path, DEFAULT_ENCODING);
- } catch (UnsupportedEncodingException exception) {
- final String message = "Unsupported encoding " + DEFAULT_ENCODING;
- final InternalError error = new InternalError(message);
- throw (InternalError) error.initCause(exception);
- }
- }
-
- /**
- * Parse the specified {@link String} into a {@link Path} structure.
- */
- public static Path parse(String path, String encoding)
- throws UnsupportedEncodingException {
- final List params = new ArrayList();
- final List elems = new ArrayList();
-
- /* No path, flog it! */
- if ((path == null) || (path.length() == 0)) {
- return new Path(elems, false, false, null);
- }
-
- /* Check for a proper encoding */
- if (encoding == null) encoding = DEFAULT_ENCODING;
-
- /* Split up the path structure into its path element components */
- final String split[] = StringTools.splitAll(path, '/');
-
- /* Check if this path is an absolute path */
- final boolean absolute = path.charAt(0) == '/';
-
- /* Check every single path element and append it to the current one */
- Element element = null;
- for (int x = 0; x < split.length; x++) {
- if (split[x] == null) continue; /* Collapse double slashes */
- element = parsePath(split[x], params, encoding);
- if (element != null) elems.add(element);
- }
-
- /* Check if this is a collection */
- final boolean collection = ((split[split.length - 1] == null)
- || (element == null)
- || element.getName().equals(".")
- || element.getName().equals(".."));
-
- /* Setup the last path in our chain and return the first one */
- final Parameters parameters = Parameters.create(params, ';');
- return new Path(elems, absolute, collection, parameters);
- }
-
- /* ====================================================================== */
-
- /**
- * Parse a single path element like path!extra;param
.
- */
- private static Element parsePath(String path, List parameters,
- String encoding)
- throws UnsupportedEncodingException {
- final int pathEnds = StringTools.findFirst(path, "!;");
- final Element element;
-
- if (pathEnds < 0) {
- element = new Element(EncodingTools.urlDecode(path, encoding), null);
- } else if (path.charAt(pathEnds) == ';') {
- // --> pathname;pathparameter
- final String name = path.substring(0, pathEnds);
- final String param = path.substring(pathEnds + 1);
- final Parameters params = Parameters.parse(param, ';', encoding);
- if (params != null) parameters.addAll(params);
- element = new Element(EncodingTools.urlDecode(name, encoding), null);
- } else {
- // --> pathname!extra...
- final String name = path.substring(0, pathEnds);
- final String more = path.substring(pathEnds + 1);
- final String split[] = StringTools.splitOnce(more, ';', false);
- final Parameters params = Parameters.parse(split[1], ';', encoding);
- if (params != null) parameters.addAll(params);
- element = new Element(EncodingTools.urlDecode(name, encoding),
- EncodingTools.urlDecode(split[0], encoding));
- }
- if (element.toString().length() == 0) return null;
- return element;
- }
-
- /* ====================================================================== */
- /* RESOLUTION METHODS */
- /* ====================================================================== */
-
- /**
- * Resolve the specified {@link Path} against this one.
- */
- public Path resolve(Path path) {
- /* Merge the parameters */
- final List params = new ArrayList();
- if (this.parameters != null) params.addAll(this.parameters);
- if (path.parameters != null) params.addAll(path.parameters);
- final Parameters parameters = Parameters.create(params, ';');
-
- /* No path, return this instance */
- if (path == null) return this;
-
- /* If the target is absolute, only merge the parameters */
- if (path.absolute)
- return new Path(path, true, path.collection, parameters);
-
- /* Resolve the path */
- final Stack source = new Stack();
- source.addAll(this);
- if (! this.collection && (source.size() > 0)) source.pop();
- final List resolved = resolve(source, this.absolute, path);
-
- /* Figure out if the resolved path is a collection and return it */
- final boolean c = path.size() == 0 ? this.collection : path.collection;
- return new Path(resolved, this.absolute, c, parameters);
- }
-
- /**
- * Parse the specified {@link String} into a {@link Path} and resolve it
- * against this one.
- */
- public Path resolve(String path) {
- try {
- return this.resolve(parse(path, DEFAULT_ENCODING));
- } catch (UnsupportedEncodingException exception) {
- final String message = "Unsupported encoding " + DEFAULT_ENCODING;
- final InternalError error = new InternalError(message);
- throw (InternalError) error.initCause(exception);
- }
- }
-
- /**
- * Parse the specified {@link String} into a {@link Path} and resolve it
- * against this one.
- *
- * @throws NullPointerException if the path {@link String} was null.
- */
- public Path resolve(String path, String encoding)
- throws UnsupportedEncodingException {
- if (encoding == null) encoding = DEFAULT_ENCODING;
- if (path == null) return this;
- return this.resolve(parse(path, encoding));
- }
-
- /* ====================================================================== */
-
- private static Stack resolve(Stack stack, boolean absolute, List elements) {
- /* If we have no source stack we create a new empty one */
- if (stack == null) stack = new Stack();
- /* A flag indicating whether we are at the "root" path element. */
- boolean atroot = absolute && stack.empty();
- /* Iterate through the current path elements to see what to do. */
- for (Iterator iter = elements.iterator(); iter.hasNext(); ) {
- final Element element = (Element) iter.next();
- /* If this is the "." (current) path element, skip it. */
- if (".".equals(element.getName())) continue;
- /* If this is the ".." (parent) path element, it gets nasty. */
- if ("..".equals(element.getName())) {
- /* The root path's parent is always itself */
- if (atroot) continue;
- /* We're not at root and have the stack, relative ".." */
- if (stack.size() == 0) {
- stack.push(element);
- /* We're not at root, but we have stuff in the stack */
- } else {
- /* Get the last element in the stack */
- final Element prev = (Element) stack.peek();
- /* If the last element is "..", add another one */
- if ("..".equals(prev.getName())) stack.push(element);
- /* The last element was not "..", pop it out */
- else stack.pop();
- /* If absoulte and stack is empty, we're at root */
- if (absolute) atroot = stack.size() == 0;
- }
- } else {
- /* Normal element processing follows... */
- stack.push(element);
- atroot = false;
- }
- }
- return stack;
- }
-
- /* ====================================================================== */
- /* RELATIVIZATION METHODS */
- /* ====================================================================== */
-
- /**
- * Parse the specified {@link String} into a {@link Path} and relativize
- * it against this one.
- */
- public Path relativize(String path) {
- try {
- return this.relativize(parse(path, DEFAULT_ENCODING));
- } catch (UnsupportedEncodingException exception) {
- final String message = "Unsupported encoding " + DEFAULT_ENCODING;
- final InternalError error = new InternalError(message);
- throw (InternalError) error.initCause(exception);
- }
- }
-
- /**
- * Parse the specified {@link String} into a {@link Path} and relativize
- * it against this one.
- */
- public Path relativize(String path, String encoding)
- throws UnsupportedEncodingException {
- if (encoding == null) encoding = DEFAULT_ENCODING;
- return this.relativize(parse(path, encoding));
- }
-
- /**
- * Retrieve the relativization path from this {@link Path} to the
- * specified {@link Path}.
- */
- public Path relativize(Path path) {
- /* No matter what, always return the aggregate of all parameters */
- final List parameters = new ArrayList();
- if (this.parameters != null) parameters.addAll(this.parameters);
- if (path.parameters != null) parameters.addAll(path.parameters);
- final Parameters params = Parameters.create(parameters, ';');
-
- /* We are absolute and the specified path is absolute, we process */
- if ((path.absolute) && (this.absolute)) {
- /* Find the max number of paths we should examine */
- final int num = this.collection ? this.size() : this.size() - 1;
-
- /* Process the two absolute paths to check common elements */
- int skip = 0;
- for (int x = 0; (x < num) && (x < path.size()); x ++) {
- if (path.paths[x].equals(this.paths[x])) skip ++;
- else break;
- }
-
- /* Figure out if the resulting path is a collection */
- final boolean collection;
- if (path.size() > skip) collection = path.collection;
- else if (this.size() > skip) collection = true;
- else collection = this.collection;
-
- /* Recreate the path to return by adding ".." and the paths */
- final List elems = new ArrayList();
- for (int x = skip; x < num; x ++) elems.add(new Element("..", null));
- elems.addAll(path.subList(skip, path.size()));
- return new Path(elems, false, collection);
- }
-
- /*
- * Here we are in one of the following cases:
- * - the specified path is already relative, so why bother?
- * - we are relative and the specified path is absolute: in this case
- * we can't possibly know how far away we are located from the root
- * so, we only have one option, to return the absolute path.
- * In all cases, though, before returning the specified path, we just
- * merge ours and the path's parameters.
- */
- if (this.absolute && (! path.absolute)) {
- /*
- * Ok, let's bother, we're absolute and the specified is not. This
- * means that if we resolve the path, we can find another absolute
- * path, and therefore we can do a better job at relativizin it.
- */
- return this.relativize(this.resolve(path));
- }
- /* We'll never going to be able to do better than this */
- return new Path(path, path.absolute, path.collection, params);
- }
-
- /* ====================================================================== */
- /* PUBLIC EXPOSED METHODS */
- /* ====================================================================== */
-
- /**
- * Return the {@link Path.Element Element} instance at
- * the specified index.
- */
- public Object get(int index) {
- return this.paths[index];
- }
-
- /**
- * Return the number of {@link Path.Element Element}
- * instances contained by this instance.
- */
- public int size() {
- return this.paths.length;
- }
-
- /**
- * Checks if this {@link Path Path} instance represents
- * an absolute path.
- */
- public boolean isAbsolute() {
- return this.absolute;
- }
-
- /**
- * Checks if this {@link Path Path} instance represents
- * a collection.
- */
- public boolean isCollection() {
- return this.collection;
- }
-
- /**
- * Returns the collection of {@link Parameters Parameters}
- * contained by this instance or null.
- */
- public Parameters getParameters() {
- return this.parameters;
- }
-
- /* ====================================================================== */
- /* OBJECT METHODS */
- /* ====================================================================== */
-
- /**
- * Return the URL-encoded {@link String} representation of this
- * {@link Path Path} instance.
- */
- public String toString() {
- return this.string;
- }
-
- /**
- * Return the URL-encoded {@link String} representation of this
- * {@link Path Path} instance using the specified
- * character encoding.
- */
- public String toString(String encoding)
- throws UnsupportedEncodingException {
- StringBuffer buffer = new StringBuffer();
- if (this.absolute) buffer.append('/');
- final int last = this.paths.length - 1;
- for (int x = 0; x < last; x ++) {
- buffer.append(this.paths[x].toString(encoding)).append('/');
- }
- if (last >= 0) {
- buffer.append(this.paths[last].toString(encoding));
- if (this.collection) buffer.append('/');
- }
- if (this.parameters != null)
- buffer.append(';').append(this.parameters.toString(encoding));
- return buffer.toString();
- }
-
- /**
- * Return the hash code value of this
- * {@link Path Path} instance.
- */
- public int hashCode() {
- return this.string.hashCode();
- }
-
- /**
- * Check if the specified {@link Object} is equal to this
- * {@link Path Path} instance.
- *
- * The specified {@link Object} is considered equal to this one if
- * it is non-null, is a {@link Path Path}
- * instance and its {@link #toString() string representation} equals
- * this one's.
- */
- public boolean equals(Object object) {
- if ((object != null) && (object instanceof Path)) {
- return this.string.equals(((Path) object).string);
- }
- return false;
- }
-
- /* ====================================================================== */
- /* PUBLIC INNER CLASSES */
- /* ====================================================================== */
-
- /**
- * The {@link Path.Element Element} class represents a path
- * element within the {@link Path Path} structure.
- *
- * @author Pier Fumagalli
- */
- public static class Element implements Encodable {
-
- /** The name of this path element (decoded).
*/
- private final String name;
- /** The extra path information of this path element (decoded).
*/
- private final String extra;
- /** The {@link String} representation of this (encoded).
*/
- private final String string;
-
- /**
- * Create a new {@link Path.Element Element} instance given its
- * url-decoded components name and extra.
- *
- * @throws NullPointerException if the specified name was null.
- */
- public Element(String name, String extra) {
- if (name == null) throw new NullPointerException("Null path name");
- this.name = name;
- this.extra = extra;
- this.string = EncodingTools.toString(this);
- }
-
- /* ================================================================== */
- /* PUBLIC EXPOSED METHODS */
- /* ================================================================== */
-
- /**
- * Return the url-decoded {@link String} name of this
- * {@link Path.Element Element}.
- */
- public String getName() {
- return this.name;
- }
-
- /**
- * Return the url-decoded {@link String} extra path of this
- * {@link Path.Element Element}.
- */
- public String getExtra() {
- return this.extra;
- }
-
- /* ================================================================== */
- /* OBJECT METHODS */
- /* ================================================================== */
-
- /**
- * Return the URL-encoded {@link String} representation of this
- * {@link Path.Element Element} instance.
- */
- public String toString() {
- return this.string;
- }
-
- /**
- * Return the URL-encoded {@link String} representation of this
- * {@link Path.Element Element} instance using the specified
- * character encoding.
- */
- public String toString(String encoding)
- throws UnsupportedEncodingException {
- final StringBuffer buffer = new StringBuffer();
- buffer.append(EncodingTools.urlEncode(this.name, encoding));
- if (this.extra != null) {
- buffer.append('!');
- buffer.append(EncodingTools.urlEncode(this.extra, encoding));
- }
- return buffer.toString();
- }
-
- /**
- * Return the hash code value of this
- * {@link Path.Element Element} instance.
- */
- public int hashCode() {
- return this.string.hashCode();
- }
-
- /**
- * Check if the specified {@link Object} is equal to this
- * {@link Path.Element Element} instance.
- *
- * The specified {@link Object} is considered equal to this one if
- * it is non-null, is a {@link Path.Element Element}
- * instance and its {@link #toString() string representation} equals
- * this one's.
- */
- public boolean equals(Object object) {
- if ((object != null) && (object instanceof Element)) {
- return this.string.equals(((Element) object).string);
- }
- return false;
- }
- }
-}
\ No newline at end of file
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/location/package.html b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/location/package.html
deleted file mode 100644
index 155907e08..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/location/package.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
- Location Utilities
-
-
-
- This package contains a number of utility classes to parse and
- work with URLs.
-
-
- The {@link java.net.URL} class already provides most of the functionality
- covered by this package, but certain limitations in its implementation
- (for example, all schemes must be registered with the
- {java.net.URLStreamHandler} class before they can be used), prompted
- the re-development of a similar API.
-
-
- For further details on what the different classes in this package mean
- and how they interact, see the {@link it.could.util.location.Location}
- class documentation, but as a reference, this is a picture outlining
- the structure:
-
-
-
-
\ No newline at end of file
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/package.html b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/package.html
deleted file mode 100644
index 97f56c6e2..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/util/package.html
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- Encoding Utilities
-
-
-
- This package contains a number of utility classes which can come handy
- from time to time when writing Java code.
-
-
-
\ No newline at end of file
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVException.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVException.java
deleted file mode 100644
index e263eeb59..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVException.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-
-
-/**
- * A {@link RuntimeException} representing a
- * WebDAV
- * response for a specified {@link DAVResource}.
- *
- * @author Pier Fumagalli
- */
-public class DAVException extends RuntimeException {
-
- private DAVResource resource = null;
- private int status = 0;
-
- /**
- * Create a new {@link DAVException} instance.
- */
- public DAVException(int status, String message) {
- this(status, message, null, null);
- }
-
- /**
- * Create a new {@link DAVException} instance.
- */
- public DAVException(int status, String message, Throwable throwable) {
- this(status, message, throwable, null);
- }
-
- /**
- * Create a new {@link DAVException} instance.
- */
- public DAVException(int status, String message, DAVResource resource) {
- this(status, message, null, resource);
- }
-
- /**
- * Create a new {@link DAVException} instance.
- */
- public DAVException(int s, String m, Throwable t, DAVResource r) {
- super(m, t);
- this.resource = r;
- this.status = s;
- }
-
- /**
- * Return the status code associated with this instance.
- */
- public int getStatus() {
- return this.status;
- }
-
- /**
- * Return the {@link DAVResource} associated with this instance.
- */
- public DAVResource getResource() {
- return this.resource;
- }
-
- /**
- * Write the body of this {@link DAVException} to the specified
- * {@link DAVTransaction}'s output.
- */
- public void write(DAVTransaction transaction)
- throws IOException {
- transaction.setContentType("text/html; charset=\"UTF-8\"");
- transaction.setStatus(this.getStatus());
-
- /* Prepare and log the error message */
- String message = DAVUtilities.getStatusMessage(this.getStatus());
- if (message == null) {
- transaction.setStatus(500);
- message = Integer.toString(this.getStatus()) + " Unknown";
- }
-
- /* Write the error message to the client */
- PrintWriter out = transaction.write("UTF-8");
- out.println("");
- out.print("Error ");
- out.print(message);
- out.println("");
- out.println("");
- out.print("Error ");
- out.print(message);
- out.println("
");
-
- /* Check if we have a resource associated with the extension */
- if (this.getResource() != null) {
- String r = transaction.lookup(this.getResource()).toASCIIString();
- out.print("Resource in error: ");
- out.print(r);
- out.println("
");
- }
-
- /* Process any exception and its cause */
- Throwable throwable = this;
- out.println("
Exception details:
");
- while (throwable != null) {
- out.print("");
- throwable.printStackTrace(out);
- out.println("
");
- throwable = throwable.getCause();
- if (throwable != null) out.println("
Caused by:
");
- }
-
- /* Close up the HTML */
- out.println("");
- out.println("");
- out.flush();
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVInputStream.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVInputStream.java
deleted file mode 100644
index 6a0976c71..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVInputStream.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-
-/**
- * A specialized {@link InputStream} to read from {@link DAVResource}s.
- *
- * This specialized {@link InputStream} never throws {@link IOException}s,
- * but rather relies on the unchecked {@link DAVException} to notify the
- * framework of the correct DAV errors.
- *
- * @author Pier Fumagalli
- */
-public class DAVInputStream extends InputStream {
-
- /** The {@link InputStream} of the source {@link File}.
*/
- protected InputStream input = null;
- /** The {@link DAVResource} associated with this instance.
*/
- private DAVResource resource = null;
-
- /**
- * Create a new {@link DAVInputStream} instance.
- */
- protected DAVInputStream(DAVResource resource) {
- if (resource == null) throw new NullPointerException();
- init(resource);
- }
-
- protected void init(DAVResource resource)
- {
- try {
- this.input = new FileInputStream(resource.getFile());
- } catch (IOException e) {
- String message = "Unable to read from resource";
- throw new DAVException (403, message, e, resource);
- }
- }
-
- /**
- * Read data from this {@link InputStream}.
- */
- public int read() {
- if (this.input == null) throw new IllegalStateException("Closed");
- try {
- return input.read();
- } catch (IOException e) {
- throw new DAVException(403, "Can't read data", e, this.resource);
- }
- }
-
- /**
- * Read data from this {@link InputStream}.
- */
- public int read(byte b[]) {
- if (this.input == null) throw new IllegalStateException("Closed");
- try {
- return input.read(b);
- } catch (IOException e) {
- throw new DAVException(403, "Can't read data", e, this.resource);
- }
- }
-
- /**
- * Read data from this {@link InputStream}.
- */
- public int read(byte b[], int off, int len) {
- if (this.input == null) throw new IllegalStateException("Closed");
- try {
- return input.read(b, off, len);
- } catch (IOException e) {
- throw new DAVException(403, "Can't read data", e, this.resource);
- }
- }
-
- /**
- * Skip a specified amount of data reading from this
- * {@link InputStream}.
- */
- public long skip(long n) {
- if (this.input == null) throw new IllegalStateException("Closed");
- try {
- return input.skip(n);
- } catch (IOException e) {
- throw new DAVException(403, "Can't skip over", e, this.resource);
- }
- }
-
- /**
- * Return the number of bytes that can be read or skipped from this
- * {@link InputStream} without blocking.
- */
- public int available() {
- if (this.input == null) throw new IllegalStateException("Closed");
- try {
- return input.available();
- } catch (IOException e) {
- throw new DAVException(403, "Can't skip over", e, this.resource);
- }
- }
-
- /**
- * Return the number of bytes that can be read or skipped from this
- * {@link InputStream} without blocking.
- */
- public void close() {
- if (this.input == null) return;
- try {
- this.input.close();
- } catch (IOException e) {
- throw new DAVException(403, "Can't close", e, this.resource);
- } finally {
- this.input = null;
- }
- }
-
- /**
- * Marks the current position in this {@link InputStream}.
- */
- public void mark(int readlimit) {
- if (this.input == null) throw new IllegalStateException("Closed");
- this.input.mark(readlimit);
- }
-
- /**
- * Repositions this stream to the position at the time the
- * {@link #mark(int)} method was last called on this
- * {@link InputStream}.
- */
- public void reset() {
- if (this.input == null) throw new IllegalStateException("Closed");
- try {
- input.reset();
- } catch (IOException e) {
- throw new DAVException(403, "Can't reset", e, this.resource);
- }
- }
-
- /**
- * Tests if this {@link InputStream} supports the {@link #mark(int)}
- * and {@link #reset()} methods.
- */
- public boolean markSupported() {
- if (this.input == null) throw new IllegalStateException("Closed");
- return this.input.markSupported();
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVListener.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVListener.java
deleted file mode 100644
index 6357bcc16..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVListener.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav;
-
-/**
- * A simple interface identifying a {@link DAVRepository} event listener.
- *
- * @author Pier Fumagalli
- */
-public interface DAVListener {
-
- /** An event representing the creation of a collection.
*/
- public static final int COLLECTION_CREATED = 1;
- /** An event representing the deletion of a collection.
*/
- public static final int COLLECTION_REMOVED = 2;
- /** An event representing the creation of a resource.
*/
- public static final int RESOURCE_CREATED = 3;
- /** An event representing the deletion of a resource.
*/
- public static final int RESOURCE_REMOVED = 4;
- /** An event representing the modification of a resource.
*/
- public static final int RESOURCE_MODIFIED = 5;
-
- /**
- * Notify this {@link DAVListener} of an action occurred on a
- * specified {@link DAVResource}.
- *
- * @param resource the {@link DAVResource} associated with the notification.
- * @param event a number identifying the type of the notification.
- */
- public void notify(DAVResource resource, int event);
-
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVLogger.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVLogger.java
deleted file mode 100644
index 9ba48466d..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVLogger.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav;
-
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
-
-/**
- * A simplicisting class defining an esay way to log stuff to the
- * {@link ServletContext}.
- *
- * @author Pier Fumagalli
- */
-public class DAVLogger {
-
- private final ServletContext context;
- private final String servletName;
- private final boolean debug;
-
- /**
- * Create a new {@link DAVLogger} from a {@link ServletConfig}.
- */
- public DAVLogger(ServletConfig config, boolean debug) {
- this.context = config.getServletContext();
- this.servletName = config.getServletName();
- this.debug = debug;
- }
-
- /**
- * Log a debug message to the context logger.
- */
- public void debug(String message) {
- if (this.debug) this.doLog(message, null);
- }
-
- /**
- * Log a debug message and related exception to the context logger.
- */
- public void debug(String message, Throwable throwable) {
- if (this.debug) this.doLog(message, throwable);
- }
-
- /**
- * Log a message to the context logger.
- */
- public void log(String message) {
- this.doLog(message, null);
- }
-
- /**
- * Log a message and related exception to the context logger.
- */
- public void log(String message, Throwable throwable) {
- this.doLog(message, throwable);
- }
-
- /**
- * Internal method for formatting messages and logging.
- */
- private void doLog(String message, Throwable throwable) {
- if ((message == null) && (throwable == null)) return;
- if ((message == null) || ("".equals(message))) message = "No message";
-
- StringBuffer buffer = new StringBuffer();
- buffer.append('[');
- buffer.append(this.servletName);
- buffer.append("] ");
- buffer.append(message);
- if (throwable == null) this.context.log(buffer.toString());
- else this.context.log(buffer.toString(), throwable);
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVMethod.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVMethod.java
deleted file mode 100644
index e73eb52b5..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVMethod.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav;
-
-import java.io.IOException;
-
-
-/**
- * An interface describing the implementation of a
- * WebDAV
- * method.
- *
- * @author Pier Fumagalli
- */
-public interface DAVMethod {
-
- /**
- * Process the specified {@link DAVTransaction}.
- *
- * @param transaction An object encapsulaing a WebDAV request/response.
- * @param resource The {@link DAVResource} to process.
- * @throws IOException If an I/O error occurred.
- */
- public void process(DAVTransaction transaction, DAVResource resource)
- throws IOException;
-
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVMultiStatus.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVMultiStatus.java
deleted file mode 100644
index e7c2fc5da..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVMultiStatus.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-
-/**
- * A {@link DAVException} representing a
- * WebDAV
- * 207
(Multi-Status) response.
- *
- * @author Pier Fumagalli
- */
-public class DAVMultiStatus extends DAVException {
-
- private Set responses = new HashSet();
-
- /**
- * Create a new {@link DAVMultiStatus} instance.
- */
- public DAVMultiStatus() {
- super(207, "Multi-Status response");
- }
-
- /**
- * Write the body of the multi-status response to the specified
- * {@link DAVTransaction}'s output.
- */
- public void write(DAVTransaction transaction)
- throws IOException {
- /* What to do on a collection resource */
- transaction.setStatus(207);
- transaction.setContentType("text/xml; charset=\"UTF-8\"");
- PrintWriter out = transaction.write("UTF-8");
-
- /* Output the XML declaration and the root document tag */
- out.println("");
- out.println("");
-
- Iterator responses = this.responses.iterator();
- while (responses.hasNext()) {
- Response response = (Response) responses.next();
- out.println(" ");
- out.print(" ");
- out.print(transaction.lookup(response.resource));
- out.println("");
-
- if (response.status != 0) {
- out.print(" HTTP/1.1 ");
- out.print(DAVUtilities.getStatusMessage(response.status));
- out.println("");
- }
-
- if (response.message != null) {
- out.print(" ");
- out.print(response.message);
- out.println("");
- }
-
- out.println(" ");
- }
-
- out.println("");
- out.flush();
- }
-
- /**
- * Return the number of responses held in this instance.
- */
- public int size() {
- return this.responses.size();
- }
-
- /**
- * Merge the responses held into the specified {@link DAVMultiStatus}
- * into this instance.
- */
- public void merge(DAVMultiStatus multistatus) {
- if (multistatus == null) return;
- Iterator iterator = multistatus.responses.iterator();
- while (iterator.hasNext()) this.responses.add(iterator.next());
- }
-
- /**
- * Merge the details held into the specified {@link DAVException}
- * into this instance.
- */
- public void merge(DAVException exception) {
- DAVResource resource = exception.getResource();
- if (resource == null) throw exception;
-
- int status = exception.getStatus();
- String message = exception.getMessage();
- this.responses.add(new Response(resource, status, message));
- }
-
- private static class Response implements Comparable {
- private DAVResource resource = null;
- private int status = 0;
- private String message = null;
-
- public Response(Response response) {
- this(response.resource, response.status, response.message);
- }
-
- public Response(DAVResource resource, int status, String message) {
- if (resource == null) throw new NullPointerException();
- this.resource = resource;
- this.status = status;
- this.message = message;
- }
-
- public int hashCode() {
- return this.resource.hashCode();
- }
-
- public int compareTo(Object object) {
- Response response = (Response) object;
- return (this.resource.compareTo(response.resource));
- }
-
- public boolean equals(Object object) {
- if (object instanceof Response) {
- Response response = (Response) object;
- return (this.resource.equals(response.resource));
- }
- return false;
- }
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVNotModified.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVNotModified.java
deleted file mode 100644
index 2d6726551..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVNotModified.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav;
-
-import java.io.IOException;
-
-/**
- * A simple {@link DAVException} encapsulating an
- * HTTP not modified
- * response.
- *
- * @author Pier Fumagalli
- */
-public class DAVNotModified extends DAVException {
-
- private DAVResource resource = null;
-
- /**
- * Create a new {@link DAVNotModified} instance.
- */
- public DAVNotModified(DAVResource resource) {
- super(304, "Resource Not Modified");
- this.resource = resource;
- }
-
- /**
- * Write the body of this {@link DAVNotModified} to the specified
- * {@link DAVTransaction}'s output.
- */
- public void write(DAVTransaction transaction)
- throws IOException {
- transaction.setStatus(this.getStatus());
-
- /* Figure out what we're dealing with here */
- String etag = resource.getEntityTag();
- String lmod = DAVUtilities.formatHttpDate(resource.getLastModified());
-
- /* Set the normal headers that are required for a GET */
- if (etag != null) transaction.setHeader("ETag", etag);
- if (lmod != null) transaction.setHeader("Last-Modified", lmod);
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVOutputStream.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVOutputStream.java
deleted file mode 100644
index 6a5c80601..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVOutputStream.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-
-/**
- * A specialized {@link OutputStream} to write to {@link DAVResource}s.
- *
- * When writing to this {@link OutputStream} the data will be written to
- * a temporary file. This temporary file will be moved to its final destination
- * (the original file identifying the resource) when the {@link #close()}
- * method is called.
- *
- * This specialized {@link OutputStream} never throws {@link IOException}s,
- * but rather relies on the unchecked {@link DAVException} to notify the
- * framework of the correct DAV errors.
- *
- * @author Pier Fumagalli
- */
-public class DAVOutputStream extends OutputStream {
-
- /** The original resource {@link File}.
*/
- private File temporary = null;
- /** The {@link OutputStream} of the temporary {@link File}.
*/
- protected OutputStream output = null;
- /** The {@link DAVResource} associated with this instance.
*/
- private DAVResource resource = null;
-
- /**
- * Create a new {@link DAVOutputStream} instance.
- */
- protected DAVOutputStream(DAVResource resource) {
- if (resource == null) throw new NullPointerException();
- this.resource = resource;
- init(resource);
- }
-
- protected void init(DAVResource resource) {
- try {
- this.temporary = resource.getParent().getFile();
- this.temporary = File.createTempFile(DAVResource.PREFIX,
- DAVResource.SUFFIX,
- this.temporary);
- this.output = new FileOutputStream(this.temporary);
- } catch (IOException e) {
- String message = "Unable to create temporary file";
- throw new DAVException(507, message, e, resource);
- }
- }
-
- /**
- * Rename the temporary {@link File} to the original one.
- */
- protected void rename(File temporary, File original)
- throws IOException {
- if ((original.exists()) && (!original.delete())) {
- throw new IOException("Unable to delete original file");
- }
- if (!temporary.renameTo(original)) {
- throw new IOException("Unable to rename temporary file");
- }
- }
-
- /**
- * Abort any data written to the temporary file and delete it.
- */
- public void abort() {
- if (this.temporary.exists()) this.temporary.delete();
- if (this.output != null) try {
- this.output.close();
- } catch (IOException exception) {
- // Swallow the IOException on close
- } finally {
- this.output = null;
- }
- }
-
- /**
- * Close this {@link OutputStream} {@link #rename(File,File) renaming}
- * the temporary file to the {@link DAVResource#getFile() original} one.
- */
- public void close() {
- if (this.output == null) return;
- try {
- /* What kind of event should this invocation trigger? */
- int event = this.resource.getFile().exists() ?
- DAVListener.RESOURCE_MODIFIED:
- DAVListener.RESOURCE_CREATED;
-
- /* Make sure that everything is closed and named properly */
- this.output.close();
- this.output = null;
- this.rename(this.temporary, this.resource.getFile());
-
- /* Send notifications to all listeners of the repository */
- this.resource.getRepository().notify(this.resource, event);
-
- } catch (IOException e) {
- String message = "Error processing temporary file";
- throw new DAVException(507, message, e, this.resource);
- } finally {
- this.abort();
- }
- }
-
- /**
- * Flush any unwritten data to the disk.
- */
- public void flush() {
- if (this.output == null) throw new IllegalStateException("Closed");
- try {
- this.output.flush();
- } catch (IOException e) {
- this.abort();
- String message = "Unable to flush buffers";
- throw new DAVException(507, message, e, this.resource);
- }
- }
-
- /**
- * Write data to this {@link OutputStream}.
- */
- public void write(int b) {
- if (this.output == null) throw new IllegalStateException("Closed");
- try {
- this.output.write(b);
- } catch (IOException e) {
- this.abort();
- String message = "Unable to write data";
- throw new DAVException(507, message, e, this.resource);
- }
- }
-
- /**
- * Write data to this {@link OutputStream}.
- */
- public void write(byte b[]) {
- if (this.output == null) throw new IllegalStateException("Closed");
- try {
- this.output.write(b);
- } catch (IOException e) {
- this.abort();
- String message = "Unable to write data";
- throw new DAVException(507, message, e, this.resource);
- }
- }
-
- /**
- * Write data to this {@link OutputStream}.
- */
- public void write(byte b[], int o, int l) {
- if (this.output == null) throw new IllegalStateException("Closed");
- try {
- this.output.write(b, o, l);
- } catch (IOException e) {
- this.abort();
- String message = "Unable to write data";
- throw new DAVException(507, message, e, this.resource);
- }
- }
-
- /**
- * Finalize this {@link DAVOutputStream} instance.
- */
- public void finalize() {
- this.abort();
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVProcessor.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVProcessor.java
deleted file mode 100644
index d50b65875..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVProcessor.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-/**
- * The WebDAV
- * transactions processor.
- *
- * @author Pier Fumagalli
- */
-public class DAVProcessor {
-
- /** All the implemented methods, comma separated.
*/
- public static final String METHODS = "COPY,DELETE,GET,HEAD,MKCOL,MOVE," +
- "OPTIONS,PROPFIND,PROPPATCH,PUT";
-
- /** A static map of all known webdav methods.
*/
- private static Map INSTANCES = new HashMap();
- static {
- /* Load and verify all the known methods */
- final String thisName = DAVProcessor.class.getName();
- final int packageDelimiter = thisName.lastIndexOf('.');
- final String packageName = packageDelimiter < 1 ? "methods." :
- thisName.substring(0, packageDelimiter) + ".methods.";
- final StringTokenizer tokenizer = new StringTokenizer(METHODS, ",");
- final ClassLoader classLoader = DAVProcessor.class.getClassLoader();
- while (tokenizer.hasMoreTokens()) try {
- final String method = tokenizer.nextToken();
- final String className = packageName + method;
- final Class clazz = classLoader.loadClass(className);
- INSTANCES.put(method, (DAVMethod) clazz.newInstance());
- } catch (Throwable throwable) {
- InternalError error = new InternalError("Error loading method");
- throw (InternalError) error.initCause(throwable);
- }
- }
-
- /** The {@link DAVRepository} associated with this instance.
*/
- private DAVRepository repository = null;
-
- /**
- * Create a new {@link DAVProcessor} instance.
- */
- public DAVProcessor(DAVRepository repository) {
- if (repository == null) throw new NullPointerException();
- this.repository = repository;
- }
-
- /**
- * Process the specified {@link DAVTransaction} fully.
- */
- public void process(DAVTransaction transaction)
- throws IOException {
- try {
- String method = transaction.getMethod();
- if (INSTANCES.containsKey(method)) {
- String path = transaction.getNormalizedPath();
- DAVResource resource = this.repository.getResource(path);
- DAVMethod instance = ((DAVMethod) INSTANCES.get(method));
- instance.process(transaction, resource);
- } else {
- String message = "Method \"" + method + "\" not implemented";
- throw new DAVException(501, message);
- }
- } catch (DAVException exception) {
- exception.write(transaction);
- }
- }
-
- public void setMethod( String methodKey, DAVMethod method ) {
- INSTANCES.put( methodKey, method );
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVRepository.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVRepository.java
deleted file mode 100644
index aa3ed42d4..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVRepository.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-/**
- * A simple class representing a {@link File} based WebDAV repository.
- *
- * @author Pier Fumagalli
- */
-public class DAVRepository {
-
- /** A {@link String} of all acceptable characters in a URI.
*/
- private static final String ACCEPTABLE =
- "ABCDEFGHIJLKMNOPQRSTUVWXYZ" + // ALPHA (UPPER)
- "abcdefghijklmnopqrstuvwxyz" + // ALPHA (LOWER)
- "0123456789" + // DIGIT
- "_-!.~'()*" + // UNRESERVED
- ",;:$&+=" + // PUNCT
- "?/[]@"; // RESERVED
-
-
- /** The {@link File} identifying the root of this repository.
*/
- protected File root = null;
- /** The {@link URI} associated with the root of this repository.
*/
- protected URI base = null;
- /** The {@link Set} of all configured {@link DAVListener}s.
*/
- private Set listeners = new HashSet();
-
- /**
- * Create a new {@link DAVRepository} instance.
- *
- * @param root The {@link File} identifying the root of the repository.
- * @throws IOException If the specified root is not a directory.
- * @throws NullPointerExceptoin If the specified root was null.
- */
- public DAVRepository(File root)
- throws IOException {
- init(root);
- }
-
- protected void init(File root)
- throws IOException {
- if (root == null) throw new NullPointerException("Null root");
- if (root.isDirectory()) {
- this.root = root.getCanonicalFile();
- this.base = this.root.toURI().normalize();
- } else {
- throw new IOException("Root \"" + root + "\" is not a directory");
- }
- }
-
- /**
- * Return the {@link URI} representing the root directory of this
- * {@link DAVRepository}.
- *
- * @return a non-null {@link URI} instance.
- */
- protected URI getRepositoryURI() {
- return (this.base);
- }
-
- /**
- * Return the {@link DAVResource} associated with the given name.
- *
- * @param name a {@link String} identifying the resource name.
- * @return a non-null {@link DAVResource} instance.
- * @throws IOException If the resource could not be resolved.
- */
- public DAVResource getResource(String name)
- throws IOException {
- if (name == null) return this.getResource((URI) null);
-
- try {
- /* Encode the string into a URI */
- StringBuffer buffer = new StringBuffer();
- byte encoded[] = name.getBytes("UTF-8");
- for (int x = 0; x < encoded.length; x ++) {
- if (ACCEPTABLE.indexOf((int)encoded[x]) < 0) {
- buffer.append('%');
- buffer.append(DAVUtilities.toHexString(encoded[x]));
- continue;
- }
- buffer.append((char) encoded[x]);
- }
-
- return this.getResource(new URI(buffer.toString()));
- } catch (URISyntaxException exception) {
- String message = "Invalid resource name \"" + name + "\"";
- throw (IOException) new IOException(message).initCause(exception);
- }
- }
-
- /**
- * Return the {@link DAVResource} associated with a {@link URI}.
- *
- * If the specified {@link URI} is relative it will be resolved against
- * the root of this {@link DAVRepository}.
- *
- * @param uri an absolute or relative {@link URI} identifying the resource.
- * @return a non-null {@link DAVResource} instance.
- * @throws IOException If the resource could not be resolved.
- */
- public DAVResource getResource(URI uri)
- throws IOException {
- if (uri == null) return new DAVResource(this, this.root);
-
- if (! uri.isAbsolute()) uri = this.base.resolve(uri).normalize();
- return new DAVResource(this, new File(uri).getAbsoluteFile());
- }
-
- /**
- * Add a new {@link DAVListener} to the list of instances notified by
- * this {@link DAVRepository}.
- */
- public void addListener(DAVListener listener) {
- if (listener != null) this.listeners.add(listener);
- }
-
- /**
- * Remove a {@link DAVListener} from the list of instances notified by
- * this {@link DAVRepository}.
- */
- public void removeListener(DAVListener listener) {
- if (listener != null) this.listeners.remove(listener);
- }
-
- /**
- * Notify all configured {@link DAVListener}s of an event.
- */
- protected void notify(DAVResource resource, int event) {
- if (resource == null) throw new NullPointerException("Null resource");
- if (resource.getRepository() != this)
- throw new IllegalArgumentException("Invalid resource");
-
- Iterator iterator = this.listeners.iterator();
- while (iterator.hasNext()) try {
- ((DAVListener)iterator.next()).notify(resource, event);
- } catch (RuntimeException exception) {
- // Swallow any RuntimeException thrown by listeners.
- }
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVResource.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVResource.java
deleted file mode 100644
index f2d0911ee..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVResource.java
+++ /dev/null
@@ -1,514 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.security.MessageDigest;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-
-
-/**
- * A simple representation of a WebDAV resource based on {@link File}s.
- *
- * @author Pier Fumagalli
- */
-public class DAVResource implements Comparable {
-
- /** The mime type when {@link #isCollection()} is true.
*/
- public static final String COLLECTION_MIME_TYPE = "httpd/unix-directory";
-
- /** The prefix for all temporary resources.
*/
- protected static final String PREFIX = ".dav_";
- /** The suffix for all temporary resources.
*/
- protected static final String SUFFIX = ".temp";
- /** The {@link DAVRepository} instance containing this resource.
*/
- private DAVRepository repository = null;
- /** The {@link File} associated with this resource.
*/
- private File file = null;
-
- /* ====================================================================== */
- /* Constructors */
- /* ====================================================================== */
-
- /**
- * Create a new {@link DAVResource} instance.
- */
- protected DAVResource(DAVRepository repo, File file) {
- if (repo == null) throw new NullPointerException("Null repository");
- if (file == null) throw new NullPointerException("Null resource");
- init(repo, file);
- }
-
- protected void init(DAVRepository repo, File file)
- {
- this.repository = repo;
- this.file = file;
-
- if (this.getRelativeURI().isAbsolute())
- throw new DAVException(412, "Error relativizing resource");
- }
-
- /* ====================================================================== */
- /* Generic object methods */
- /* ====================================================================== */
-
- /**
- * Return an integer number for the hash value of this instance.
- */
- public int hashCode() {
- return this.file.hashCode();
- }
-
- /**
- * Compare this instance to another object for equality.
- */
- public boolean equals(Object object) {
- if (object == null) return (false);
- if (object instanceof DAVResource) {
- DAVResource resource = (DAVResource) object;
- boolean u = this.file.equals(resource.file);
- boolean r = this.repository == resource.repository;
- return (u && r);
- } else {
- return (false);
- }
- }
-
- /**
- * Compare this instance to another object for sorting.
- */
- public int compareTo(Object object) {
- DAVResource resource = (DAVResource) object;
- return (this.file.compareTo(resource.file));
- }
-
- /* ====================================================================== */
- /* Resource checkers */
- /* ====================================================================== */
-
- /**
- * Checks if this {@link DAVResource} is a null (non existant) one.
- *
- * @return true if this resource does not esist (is a null resource).
- */
- public boolean isNull() {
- return (! this.file.exists());
- }
-
- /**
- * Checks if this {@link DAVResource} is a collection.
- *
- * @return true if this resource is a collection.
- */
- public boolean isCollection() {
- if (this.isNull()) return false;
- return (this.file.isDirectory());
- }
-
- /**
- * Checks if this {@link DAVResource} is an existing resource.
- *
- * @return true if this resource is a collection.
- */
- public boolean isResource() {
- if (this.isNull()) return false;
- return (! this.isCollection());
- }
-
- /* ====================================================================== */
- /* Resource methods */
- /* ====================================================================== */
-
- /**
- * Return the {@link File} associated with this resource.
- */
- protected File getFile() {
- return this.file;
- }
-
- /**
- * Return the {@link DAVRepository} associated with this resource.
- */
- public DAVRepository getRepository() {
- return this.repository;
- }
-
- /**
- * Return the bare name of this resource (without any "/"
- * slashes at the end if it is a collection).
- *
- * @return a non null {@link String}.
- */
- public String getName() {
- return this.file.getName();
- }
-
- /**
- * Return the display name of this resource (with an added "/"
- * slash at the end if it is a collection).
- *
- * @return a non null {@link String}.
- */
- public String getDisplayName() {
- String name = this.getName();
- if (this.isCollection()) return (name + "/");
- return name;
- }
-
- /**
- * Return the path of this {@link DAVResource} relative to the root
- * of the associated {@link DAVRepository}.
- *
- * @return a non null {@link String}.
- */
- public String getRelativePath() {
- return this.getRelativeURI().toASCIIString();
- }
-
- /**
- * Return the {@link URI} of this {@link DAVResource} relative to the
- * root of the associated {@link DAVRepository}.
- *
- * @return a non-null {@link URI} instance.
- */
- public URI getRelativeURI() {
- URI uri = this.file.toURI();
- return this.repository.getRepositoryURI().relativize(uri).normalize();
- }
-
- /**
- * Return the parent {@link DAVResource} of this instance.
- *
- * @return a non-null {@link DAVResource} instance or null
- * if this {@link DAVResource} is the repository root.
- */
- public DAVResource getParent() {
- try {
- return new DAVResource(this.repository, this.file.getParentFile());
- } catch (Throwable throwable) {
- return null;
- }
- }
-
- /**
- * Return an {@link Iterator} over all children of this instance.
- *
- * @return a non-null {@link Iterator} instance or null if
- * this {@link DAVResource} is not a collection.
- * @throws IOException If the resource could not be resolved.
- */
- public Iterator getChildren() {
- if (! this.isCollection()) return null;
-
- File children[] = this.file.listFiles();
- if (children == null) children = new File[0];
- List resources = new ArrayList(children.length);
-
- for (int x = 0; x < children.length; x++) {
- String c = children[x].getName();
- if (c.startsWith(PREFIX) && c.endsWith(SUFFIX)) continue;
- resources.add(new DAVResource(this.repository, children[x]));
- }
-
- return resources.iterator();
- }
-
- /* ====================================================================== */
- /* DAV Properties */
- /* ====================================================================== */
-
- /**
- * Return the MIME Content-Type of this {@link DAVResource}.
- *
- * If the {@link #isCollection()} method returns true this
- * method always returns text/html
.
- *
- * @return a {@link String} instance or null if this resource does
- * not exist.
- */
- public String getContentType() {
- if (this.isNull()) return null;
- if (this.isCollection()) return COLLECTION_MIME_TYPE;
- return DAVUtilities.getMimeType(this.getDisplayName());
- }
-
- /**
- * Return the MIME Content-Length of this {@link DAVResource}.
- *
- * @return a {@link Long} instance or null if this resource does
- * not exist or is a collection.
- */
- public Long getContentLength() {
- if (this.isNull() || this.isCollection()) return null;
- return new Long(this.file.length());
- }
-
- /**
- * Return the creation date of this {@link DAVResource}.
- *
- * As this implementation relies on a {@link File} backend, this method
- * will always return the same as {@link #getLastModified()}.
- *
- * @return a {@link String} instance or null if this resource does
- * not exist.
- */
- public Date getCreationDate() {
- if (this.isNull()) return null;
- return new Date(this.file.lastModified());
- }
-
- /**
- * Return the last modification date of this {@link DAVResource}.
- *
- * @return a {@link String} instance or null if this resource does
- * not exist.
- */
- public Date getLastModified() {
- if (this.isNull()) return null;
- return new Date(this.file.lastModified());
- }
-
- /**
- * Return a {@link String} representing the Entity Tag of this
- * {@link DAVResource} as described by the
- * HTTP RFC.
- *
- * @return a {@link String} instance or null if this resource does
- * not exist.
- */
- public String getEntityTag() {
- if (this.isNull()) return null;
-
- String path = this.getRelativePath();
- StringBuffer etag = new StringBuffer();
- etag.append('"');
-
- /* Append the MD5 hash of this resource name */
- try {
- MessageDigest digester = MessageDigest.getInstance("MD5");
- digester.reset();
- digester.update(path.getBytes("UTF8"));
- etag.append(DAVUtilities.toHexString(digester.digest()));
- etag.append('-');
- } catch (Exception e) {
- // If we can't get the MD5 HASH, let's ignore and hope...
- }
-
- /* Append the hashCode of this resource name */
- etag.append(DAVUtilities.toHexString(path.hashCode()));
-
- /* Append the last modification date if possible */
- Date date = this.getLastModified();
- if (date != null) {
- etag.append('-');
- etag.append(DAVUtilities.toHexString(date.getTime()));
- }
-
- /* Close the ETag */
- etag.append('"');
- return(etag.toString());
- }
-
- /* ====================================================================== */
- /* DAV Operations */
- /* ====================================================================== */
-
- /**
- * Delete this resource.
- *
- * @throws DAVException If for any reason this resource cannot be deleted.
- */
- public void delete()
- throws DAVMultiStatus {
- if (this.isNull()) throw new DAVException(404, "Not found", this);
-
- if (this.isResource()) {
- if (!windowsSafeDelete(this.file)) {
- throw new DAVException(403, "Can't delete resource", this);
- } else {
- this.repository.notify(this, DAVListener.RESOURCE_REMOVED);
- }
- } else if (this.isCollection()) {
- DAVMultiStatus multistatus = new DAVMultiStatus();
-
- Iterator children = this.getChildren();
- while (children.hasNext()) try {
- ((DAVResource)children.next()).delete();
- } catch (DAVException exception) {
- multistatus.merge(exception);
- }
-
- if (multistatus.size() > 0) throw multistatus;
- if (!this.file.delete()) {
- throw new DAVException(403, "Can't delete collection", this);
- } else {
- this.repository.notify(this, DAVListener.COLLECTION_REMOVED);
- }
- }
- }
-
- /**
- * Copy this resource to the specified destination.
- *
- * @throws DAVException If for any reason this resource cannot be deleted.
- */
- public void copy(DAVResource dest, boolean overwrite, boolean recursive)
- throws DAVMultiStatus {
-
- /*
- * NOTE: Since the COPY operation relies on other operation defined in
- * this class (and in DAVOutputStream for resources) rather than on
- * files temselves, notifications are sent elsewhere, not here.
- */
-
- if (this.isNull()) throw new DAVException(404, "Not found", this);
-
- /* Check if the destination exists and delete if possible */
- if (!dest.isNull()) {
- if (! overwrite) {
- String msg = "Not overwriting existing destination";
- throw new DAVException(412, msg, dest);
- }
- dest.delete();
- }
-
- /* Copy a single resource (destination is null as we deleted it) */
- if (this.isResource()) {
- DAVInputStream in = this.read();
- DAVOutputStream out = dest.write();
- byte buffer[] = new byte[4096];
- int k = -1;
- while ((k = in.read(buffer)) != -1) out.write(buffer, 0, k);
- in.close();
- out.close();
- }
-
- /* Copy the collection and all nested members */
- if (this.isCollection()) {
- dest.makeCollection();
- if (! recursive) return;
-
- DAVMultiStatus multistatus = new DAVMultiStatus();
- Iterator children = this.getChildren();
- while (children.hasNext()) try {
- DAVResource childResource = (DAVResource) children.next();
- File child = new File(dest.file, childResource.file.getName());
- DAVResource target = new DAVResource(this.repository, child);
- childResource.copy(target, overwrite, recursive);
- } catch (DAVException exception) {
- multistatus.merge(exception);
- }
- if (multistatus.size() > 0) throw multistatus;
- }
- }
-
- /**
- * Moves this resource to the specified destination.
- *
- * @throws DAVException If for any reason this resource cannot be deleted.
- */
- public void move(DAVResource dest, boolean overwrite, boolean recursive)
- throws DAVMultiStatus {
- // the base class implementation is just copy-then-delete
- copy(dest, overwrite, recursive);
- this.delete();
- }
-
- /**
- * Create a collection identified by this {@link DAVResource}.
- *
- * This resource must be {@link #isNull() non-null} and its
- * {@link #getParent() parent} must be accessible and be a
- * {@link #isCollection() collection}.
- *
- * @throws DAVException If for any reason a collection identified by this
- * resource cannot be created.
- */
- public void makeCollection() {
- DAVResource parent = this.getParent();
- if (!this.isNull())
- throw new DAVException(405, "Resource exists", this);
- if (parent.isNull())
- throw new DAVException(409, "Parent does not not exist", this);
- if (!parent.isCollection())
- throw new DAVException(403, "Parent not a collection", this);
- if (!this.file.mkdir())
- throw new DAVException(507, "Can't create collection", this);
- this.repository.notify(this, DAVListener.COLLECTION_CREATED);
- }
-
- /**
- * Return an {@link InputStream} reading the resource.
- *
- * @return a non-null {@link InputStream} instance.
- */
- public DAVInputStream read() {
- if (this.isNull()) throw new DAVException(404, "Not found", this);
- if (this.isCollection())
- throw new DAVException (403, "Resource is collection", this);
- return new DAVInputStream(this);
- }
-
- /**
- * Return a {@link DAVOutputStream} writing to this {@link DAVResource}
- * instance.
- *
- * @return a non-null {@link DAVOutputStream} instance.
- */
- public DAVOutputStream write() {
- DAVResource parent = this.getParent();
- if (this.isCollection())
- throw new DAVException(409, "Can't write a collection", this);
- if (parent.isNull())
- throw new DAVException(409, "Parent doesn't exist", this);
- if (! parent.isCollection())
- throw new DAVException(403, "Parent not a collection", this);
- return new DAVOutputStream(this);
- }
-
- /** File.delete(file) sometimes fails transiently on Windows.
- * This occurs even in low-I/O conditions, with file Explorer closed.
- * Delete can still fail (correctly) due to the separate Windows problem
- * of file sharing violations.
- * @return the status of the last attempt of File.delete()
- */
- private static boolean windowsSafeDelete(File f)
- {
- // www.mail-archive.com/java-user@lucene.apache.org/msg08994.html
- boolean success = f.delete();
- int attempts = 1;
- while(!success && f.exists() && attempts < 3) {
- if(attempts > 2) {
- System.gc();
- }
- try {
- Thread.sleep(20);
- } catch (InterruptedException ignore) {
- }
- success = f.delete();
- attempts++;
- }
- return success;
- }
-
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVServlet.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVServlet.java
deleted file mode 100644
index de36a6f6c..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVServlet.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav;
-
-import javax.servlet.Servlet;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-
-/**
- * A very simple servlet capable of processing very simple
- * WebDAV
- * requests.
- *
- * @author Pier Fumagalli
- */
-public class DAVServlet implements Servlet, DAVListener {
-
- /** The {@link DAVRepository} configured for this instance.
*/
- protected DAVRepository repository = null;
- /** The {@link DAVLogger} configured for this instance.
*/
- protected DAVLogger logger = null;
- /** The {@link DAVProcessor} configured for this instance.
*/
- protected DAVProcessor processor = null;
- /** The {@link ServletContext} associated with this instance.
*/
- private ServletContext context = null;
- /** The {@link ServletConfig} associated with this instance.
*/
- private ServletConfig config= null;
-
- /**
- * Create a new {@link DAVServlet} instance.
- */
- public DAVServlet() {
- super();
- }
-
- /**
- * Initialize this {@link Servlet} instance.
- *
- * The only initialization parameter required by this servlet is the
- * "rootPath
" parameter specifying the path
- * of the repository root (either absolute or relative to the configured
- * {@link ServletContext}.
- *
- * If the specified root is relative, it will be considered to
- * be relative to the {@link ServletContext} deployment path.
- *
- * In any case, the specified root must ultimately point to an existing
- * directory on a locally-accessible file system.
- *
- * When set to true
, an optional parameter called
- * xmlOnly
will force this {@link DAVServlet} to use an
- * {@link XMLRepository} instead of the default {@link DAVRepository}.
- *
- * Finally, when set to true
, the optional parameter
- * debugEnabled
will enable logging of method invocation and
- * events in the repository.
- */
- public void init(ServletConfig config)
- throws ServletException {
- /* Remember the configuration instance */
- this.config = config;
- this.context = config.getServletContext();
-
- /* Setup logging */
- boolean debug = "true".equals(config.getInitParameter("debugEnabled"));
- this.logger = new DAVLogger(config, debug);
-
- /* Try to retrieve the WebDAV root path from the configuration */
- String rootPath = config.getInitParameter("rootPath");
- if (rootPath == null)
- throw new ServletException("Parameter \"rootPath\" not specified");
-
- /* Create repository and processor */
- try {
- File root = new File(rootPath);
- // The repository may not be the local filesystem. It may be rooted at "/".
- // But then on Windows new File("/").isAbsolute() is false.
- boolean unixAbsolute = rootPath.startsWith("/");
- boolean localAbsolute = root.isAbsolute();
- if (! unixAbsolute && !localAbsolute) {
- URL url = this.context.getResource("/" + rootPath);
- if (! "file".equals(url.getProtocol())) {
- throw new ServletException("Invalid root \"" + url + "\"");
- } else {
- root = new File(url.getPath());
- }
- }
-
- /* Discover the repository implementation at runtime */
- String repositoryClass = config.getInitParameter("repositoryClass");
- if(repositoryClass != null) {
- this.repository = DAVServlet.newRepository(repositoryClass, root);
- } else {
- // legacy configuration format. keep for now
- /* Make sure that we use the correct repository type */
- if ("true".equalsIgnoreCase(config.getInitParameter("xmlOnly"))) {
- this.repository = new XMLRepository(root);
- } else {
- this.repository = new DAVRepository(root);
- }
- }
-
- /* Initialize the processor and register ourselves as listeners */
- this.processor = new DAVProcessor(this.repository);
- this.repository.addListener(this);
- this.logger.log("Initialized from " + root.getPath());
-
- } catch (MalformedURLException e) {
- throw new ServletException("Can't resolve \"" + rootPath + "\"", e);
- } catch (IOException e) {
- String msg = "Can't initialize repository at \"" + rootPath + "\"";
- throw new ServletException(msg, e);
- }
-
- /* Finally, register this repository in the servlet context */
- final String key = getRepositoryKey(config.getServletName());
- this.context.setAttribute(key, this.repository);
- }
-
- /**
- * Retrieve a {@link DAVRepository} for a given {@link File}.
- */
- public DAVRepository getRepository(File root)
- throws IOException {
- return new XMLRepository(root);
- }
-
- /**
- * Detroy this {@link Servlet} instance.
- */
- public void destroy() {
- this.repository.removeListener(this);
- }
-
- /**
- * Return the {@link ServletConfig} associated with this instance.
- */
- public ServletConfig getServletConfig() {
- return (this.config);
- }
-
- /**
- * Return the {@link ServletContext} associated with this instance.
- */
- public ServletContext getServletContext() {
- return (this.context);
- }
-
- /**
- * Return a informative {@link String} about this servlet.
- */
- public String getServletInfo() {
- return DAVUtilities.SERVLET_INFORMATION;
- }
-
- /**
- * Execute the current request.
- */
- public void service(ServletRequest request, ServletResponse response)
- throws ServletException, IOException {
- HttpServletRequest req = (HttpServletRequest) request;
- HttpServletResponse res = (HttpServletResponse) response;
-
- /* Mark our presence */
- res.setHeader("Server", this.context.getServerInfo() + ' ' +
- DAVUtilities.SERVLET_SIGNATURE);
-
- /* Normal methods are processed by their individual instances */
- DAVTransaction transaction = new DAVTransaction(req, res);
- try {
- this.processor.process(transaction);
- } catch (RuntimeException exception) {
- final String header = req.getMethod() + ' ' + req.getRequestURI()
- + ' ' + req.getProtocol();
- this.context.log("Error processing: " + header);
- this.context.log("Exception processing DAV transaction", exception);
- throw exception;
- }
- }
-
- /* ====================================================================== */
- /* DAV LISTENER INTERFACE IMPLEMENTATION */
- /* ====================================================================== */
-
- /**
- * Receive notification of an event occurred in a specific
- * {@link DAVRepository}.
- */
- public void notify(DAVResource resource, int event) {
- String message = "Unknown event";
- switch (event) {
- case DAVListener.COLLECTION_CREATED:
- message = "Collection created";
- break;
- case DAVListener.COLLECTION_REMOVED:
- message = "Collection removed";
- break;
- case DAVListener.RESOURCE_CREATED:
- message = "Resource created";
- break;
- case DAVListener.RESOURCE_REMOVED:
- message = "Resource removed";
- break;
- case DAVListener.RESOURCE_MODIFIED:
- message = "Resource modified";
- break;
- }
- this.logger.debug(message + ": \"" + resource.getRelativePath() + "\"");
- }
-
- /* ====================================================================== */
- /* CONTEXT METHODS */
- /* ====================================================================== */
-
- /**
- * Retrieve the key in the {@link ServletContext} where the instance of
- * the {@link DAVRepository} associated with a named {@link DAVServlet}
- * can be found.
- *
- * @param servletName the name of the {@link DAVServlet} as specified in
- * the web.xml
deployment descriptor.
- */
- public static String getRepositoryKey(String servletName) {
- if (servletName == null) throw new NullPointerException();
- return DAVRepository.class.getName() + "." + servletName;
- }
-
- /** factory for subclasses configured in web.xml
- * @param repositoryClass must extend DAVRepository and have a public constructor(File).
- * */
- static DAVRepository newRepository(String repositoryClass, File root)
- throws ServletException
- {
- try {
- Class c = Class.forName(repositoryClass);
- Constructor ctor = c.getConstructor(new Class[]{File.class});
- DAVRepository repo = (DAVRepository)ctor.newInstance(new Object[]{root});
- return repo;
- } catch(ClassNotFoundException e) {
- throw new ServletException(e);
- } catch(LinkageError le) {
- throw new ServletException(le);
- } catch(NoSuchMethodException ns) {
- throw new ServletException(ns);
- } catch(InvocationTargetException it) {
- throw new ServletException(it);
- } catch(IllegalAccessException ia) {
- throw new ServletException(ia);
- } catch(InstantiationException ie) {
- throw new ServletException(ie);
- }
- }
-
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVTransaction.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVTransaction.java
deleted file mode 100644
index 20089f022..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVTransaction.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav;
-
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Date;
-
-
-/**
- * A simple wrapper isolating the Java Servlet API from this
- * WebDAV
- * implementation.
- *
- * @author Pier Fumagalli
- */
-public class DAVTransaction {
-
- /**
- * The identifyication of the infinity
value
- * in the Depth
header.
- */
- public static final int INFINITY = Integer.MAX_VALUE;
-
- /** The nested {@link HttpServletRequest}.
*/
- private HttpServletRequest request = null;
- /** The nested {@link HttpServletResponse}.
*/
- private HttpServletResponse response = null;
- /** The {@link URI} associated with the base of the repository.
*/
- private URI base = null;
- /** The status for the HTTP response.
*/
- private int status = -1;
-
- /* ====================================================================== */
- /* Constructors */
- /* ====================================================================== */
-
- /**
- * Create a new {@link DAVTransaction} instance.
- */
- public DAVTransaction(ServletRequest request, ServletResponse response)
- throws ServletException {
- if (request == null) throw new NullPointerException("Null request");
- if (response == null) throw new NullPointerException("Null response");
- this.request = (HttpServletRequest) request;
- this.response = (HttpServletResponse) response;
- this.response.setHeader("DAV", "1");
- this.response.setHeader("MS-Author-Via", "DAV");
-
- try {
- String scheme = this.request.getScheme();
- String host = this.request.getServerName();
- String path = this.request.getContextPath() +
- this.request.getServletPath();
- int port = this.request.getServerPort();
- if (! path.endsWith("/")) path += "/";
- this.base = new URI(scheme, null, host, port, path, null, null);
- this.base = this.base.normalize();
- } catch (URISyntaxException exception) {
- throw new ServletException("Unable to create base URI", exception);
- }
- }
-
- /* ====================================================================== */
- /* Request methods */
- /* ====================================================================== */
-
- /**
- * Return the path originally requested by the client.
- */
- public String getMethod() {
- return this.request.getMethod();
- }
-
- /**
- * Return the path originally requested by the client.
- */
- public String getOriginalPath() {
- String path = this.request.getPathInfo();
- if (path == null) return "";
- if ((path.length() > 1) && (path.charAt(0) == '/')) {
- return path.substring(1);
- } else {
- return path;
- }
- }
-
- /**
- * Return the path originally requested by the client.
- */
- public String getNormalizedPath() {
- final String path = this.getOriginalPath();
- if (! path.endsWith("/")) return path;
- return path.substring(0, path.length() - 1);
- }
-
- /**
- * Return the depth requested by the client for this transaction.
- */
- public int getDepth() {
- String depth = request.getHeader("Depth");
- if (depth == null) return INFINITY;
- if ("infinity".equalsIgnoreCase(depth)) return INFINITY;
- try {
- return Integer.parseInt(depth);
- } catch (NumberFormatException exception) {
- throw new DAVException(412, "Unable to parse depth", exception);
- }
- }
-
- /**
- * Return a {@link URI}
- */
- public URI getDestination() {
- String destination = this.request.getHeader("Destination");
- if (destination != null) try {
- return this.base.relativize(new URI(destination));
- } catch (URISyntaxException exception) {
- throw new DAVException(412, "Can't parse destination", exception);
- }
- return null;
- }
-
- /**
- *
Return the overwrite flag requested by the client for this
- * transaction.
- */
- public boolean getOverwrite() {
- String overwrite = request.getHeader("Overwrite");
- if (overwrite == null) return true;
- if ("T".equals(overwrite)) return true;
- if ("F".equals(overwrite)) return false;
- throw new DAVException(412, "Unable to parse overwrite flag");
- }
-
- /**
- * Check if the client requested a date-based conditional operation.
- */
- public Date getIfModifiedSince() {
- String name = "If-Modified-Since";
- if (this.request.getHeader(name) == null) return null;
- return new Date(this.request.getDateHeader(name));
- }
-
- /* ====================================================================== */
- /* Response methods */
- /* ====================================================================== */
-
- /**
- * Set the HTTP status code of the response.
- */
- public void setStatus(int status) {
- this.response.setStatus(status);
- this.status = status;
- }
-
- /**
- * Set the HTTP status code of the response.
- */
- public int getStatus() {
- return this.status;
- }
-
- /**
- * Set the HTTP Content-Type
header.
- */
- public void setContentType(String type) {
- this.response.setContentType(type);
- }
-
- /**
- * Set an HTTP header in the response.
- */
- public void setHeader(String name, String value) {
- this.response.setHeader(name, value);
- }
-
- /* ====================================================================== */
- /* I/O methods */
- /* ====================================================================== */
-
- /**
- * Check if there is a body in the request.
- *
- * This method differs from checking if the return value of the
- * {@link #read()} method is not null as a request body of length
- * zero will return false in this case, while in the {@link #read()}
- * method will return an empty {@link InputStream}.
- */
- public boolean hasRequestBody()
- throws IOException {
- /* We don't support ranges */
- if (request.getHeader("Content-Range") != null)
- throw new DAVException(501, "Content-Range not supported");
-
- if (this.request.getContentLength() > 0) return true;
- String len = this.request.getHeader("Content-Length");
- if (len != null) try {
- return (Long.parseLong(len) > 0);
- } catch (NumberFormatException exception) {
- throw new DAVException(411, "Invalid Content-Length specified");
- }
- return false;
- }
-
- /**
- * Read from the body of the original request.
- */
- public InputStream read()
- throws IOException {
- /* We don't support ranges */
- if (request.getHeader("Content-Range") != null)
- throw new DAVException(501, "Content-Range not supported");
-
- if (this.request.getContentLength() >= 0) {
- return this.request.getInputStream();
- }
-
- String len = this.request.getHeader("Content-Length");
- if (len != null) try {
- if (Long.parseLong(len) >= 0) return this.request.getInputStream();
- } catch (NumberFormatException exception) {
- throw new DAVException(411, "Invalid Content-Length specified");
- }
- return null;
- }
-
- /**
- * Write the body of the response.
- */
- public OutputStream write()
- throws IOException {
- return this.response.getOutputStream();
- }
-
- /**
- * Write the body of the response.
- */
- public PrintWriter write(String encoding)
- throws IOException {
- return new PrintWriter(new OutputStreamWriter(this.write(), encoding));
- }
-
- /* ====================================================================== */
- /* Lookup methods */
- /* ====================================================================== */
-
- /**
- * Look up the final URI of a {@link DAVResource} as visible from the
- * HTTP client requesting this transaction.
- */
- public URI lookup(DAVResource resource) {
- URI uri = resource.getRelativeURI();
- return this.base.resolve(uri).normalize();
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVUtilities.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVUtilities.java
deleted file mode 100644
index 5e03f1e76..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVUtilities.java
+++ /dev/null
@@ -1,420 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav;
-
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Properties;
-import java.util.StringTokenizer;
-import java.util.TimeZone;
-
-
-/**
- * A collection of static utilities.
- *
- * @author Pier Fumagalli
- */
-public final class DAVUtilities {
-
- /** A {@link HashMap} of configured mime types.
*/
- private static Map MIME_TYPES = new HashMap();
- /** A {@link HashMap} of configured mime types.
*/
- private static Properties PROPERTIES = new Properties();
- /** The {@link SimpleDateFormat} RFC-822 date format.
*/
- private static final String FORMAT_822 = "EEE, dd MMM yyyy HH:mm:ss 'GMT'";
- /** The {@link SimpleDateFormat} RFC-822 date format.
*/
- private static final String FORMAT_ISO = "yyyy-MM-dd'T'HH:mm:ss'Z'";
- /** The {@link TimeZone} to use for dates.
*/
- private static final TimeZone TIMEZONE = TimeZone.getTimeZone("GMT");
- /** The {@link Locale} to use for dates.
*/
- private static final Locale LOCALE = Locale.US;
-
- /**
- * Load the mime types map from a resource.
- */
- static {
- Class clazz = DAVUtilities.class;
- ClassLoader loader = clazz.getClassLoader();
-
- /* Load up the properties file */
- String webdavPropResource = "plexus-webdav/webdav.props";
- InputStream prop = loader.getResourceAsStream(webdavPropResource);
- if (prop != null) try {
- DAVUtilities.PROPERTIES.load(prop);
- prop.close();
- } catch (Exception exception) {
- exception.printStackTrace();
- } else {
- System.err.println("Invalid resource: " + webdavPropResource);
- }
-
- /* Load up the mime types table */
- String mimeTypeResource = "plexus-webdav/mime.types";
- InputStream mime = loader.getResourceAsStream(mimeTypeResource);
- if (mime != null) try {
- InputStreamReader read = new InputStreamReader(mime);
- BufferedReader buff = new BufferedReader(read);
- String line = null;
- while ((line = buff.readLine()) != null) {
- line = line.trim();
- if (line.length() == 0) continue;
- if (line.charAt(0) == '#') continue;
- StringTokenizer tokenizer = new StringTokenizer(line);
- if (tokenizer.countTokens() > 1) {
- String type = tokenizer.nextToken();
- while (tokenizer.hasMoreTokens()) {
- String extension = '.' + tokenizer.nextToken();
- DAVUtilities.MIME_TYPES.put(extension, type);
- }
- }
- }
- buff.close();
- read.close();
- mime.close();
- } catch (Exception exception) {
- exception.printStackTrace();
- } else {
- System.err.println("Invalid resource: " + mimeTypeResource);
- }
- }
-
- /** The signature of this package usable from a servlet.
*/
- public static final String SERVLET_SIGNATURE =
- DAVUtilities.getProperty("servlet.signature") + '/' +
- DAVUtilities.getProperty("version");
-
- /** The information detail of this package usable from a servlet.
*/
- public static final String SERVLET_INFORMATION =
- DAVUtilities.getProperty("servlet.information") + " version " +
- DAVUtilities.getProperty("version");
-
- /**
- * Deny public construction of {@link DAVUtilities} instances.
- */
- private DAVUtilities() {
- super();
- }
-
- /**
- * Return the value of a property configured for this package.
- *
- * @param name the property name
- * @return a {@link String} instance or null if unknown.
- */
- public static String getProperty(String name) {
- if (name == null) return null;
- return DAVUtilities.PROPERTIES.getProperty(name);
- }
-
- /**
- * Return the MIME Type configured for a given resource.
- *
- * @param name the resource name whose MIME Type needs to be looked up.
- * @return a {@link String} instance or null if the type is unknown.
- */
- public static String getMimeType(String name) {
- if (name == null) return null;
-
- Iterator iterator = DAVUtilities.MIME_TYPES.keySet().iterator();
- while (iterator.hasNext()) {
- String extension = (String) iterator.next();
- if (name.endsWith(extension)) {
- return (String) DAVUtilities.MIME_TYPES.get(extension);
- }
- }
-
- return null;
- }
-
- /**
- * Return a {@link String} message given an HTTP status code.
- */
- public static String getStatusMessage(int status) {
- switch (status) {
- /* HTTP/1.1 RFC-2616 */
- case 100: return "100 Continue";
- case 101: return "101 Switching Protocols";
- case 200: return "200 OK";
- case 201: return "201 Created";
- case 202: return "202 Accepted";
- case 203: return "203 Non-Authoritative Information";
- case 204: return "204 No Content";
- case 205: return "205 Reset Content";
- case 206: return "206 Partial Content";
- case 300: return "300 Multiple Choices";
- case 301: return "301 Moved Permanently";
- case 302: return "302 Found";
- case 303: return "303 See Other";
- case 304: return "304 Not Modified";
- case 305: return "305 Use Proxy";
- case 306: return "306 (Unused)";
- case 307: return "307 Temporary Redirect";
- case 400: return "400 Bad Request";
- case 401: return "401 Unauthorized";
- case 402: return "402 Payment Required";
- case 403: return "403 Forbidden";
- case 404: return "404 Not Found";
- case 405: return "405 Method Not Allowed";
- case 406: return "406 Not Acceptable";
- case 407: return "407 Proxy Authentication Required";
- case 408: return "408 Request Timeout";
- case 409: return "409 Conflict";
- case 410: return "410 Gone";
- case 411: return "411 Length Required";
- case 412: return "412 Precondition Failed";
- case 413: return "413 Request Entity Too Large";
- case 414: return "414 Request-URI Too Long";
- case 415: return "415 Unsupported Media Type";
- case 416: return "416 Requested Range Not Satisfiable";
- case 417: return "417 Expectation Failed";
- case 500: return "500 Internal Server Error";
- case 501: return "501 Not Implemented";
- case 502: return "502 Bad Gateway";
- case 503: return "503 Service Unavailable";
- case 504: return "504 Gateway Timeout";
- case 505: return "505 HTTP Version Not Supported";
-
- /* DAV/1.0 RFC-2518 */
- case 102: return "102 Processing";
- case 207: return "207 Multi-Status";
- case 422: return "422 Unprocessable Entity";
- case 423: return "423 Locked";
- case 424: return "424 Failed Dependency";
- case 507: return "507 Insufficient Storage";
-
- /* Unknown */
- default: return null;
- }
- }
-
- /**
- * Format a {@link Number} into a {@link String} making sure that
- * {@link NullPointerException}s are not thrown.
- *
- * @param number the {@link Number} to format.
- * @return a {@link String} instance or null if the object was null.
- */
- public static String formatNumber(Number number) {
- if (number == null) return null;
- return (number.toString());
- }
-
- /**
- * Parse a {@link String} into a {@link Long}.
- *
- * @param string the {@link String} to parse.
- * @return a {@link Long} instance or null if the date was null or
- * if there was an error parsing the specified {@link String}.
- */
- public static Long parseNumber(String string) {
- if (string == null) return null;
- try {
- return new Long(string);
- } catch (NumberFormatException exception) {
- return null;
- }
- }
-
- /**
- * Format a {@link Date} according to the HTTP/1.1 RFC.
- *
- * @param date the {@link Date} to format.
- * @return a {@link String} instance or null if the date was null.
- */
- public static String formatHttpDate(Date date) {
- if (date == null) return null;
- SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_822, LOCALE);
- formatter.setTimeZone(TIMEZONE);
- return formatter.format(date);
- }
-
- /**
- * Format a {@link Date} according to the ISO 8601 specification.
- *
- * @param date the {@link Date} to format.
- * @return a {@link String} instance or null if the date was null.
- */
- public static String formatIsoDate(Date date) {
- if (date == null) return null;
- SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_ISO, LOCALE);
- formatter.setTimeZone(TIMEZONE);
- return formatter.format(date);
- }
-
- /**
- * Parse a {@link String} into a {@link Date} according to the
- * HTTP/1.1 RFC (Mon, 31 Jan 2000 11:59:00 GMT
).
- *
- * @param string the {@link String} to parse.
- * @return a {@link Date} instance or null if the date was null or
- * if there was an error parsing the specified {@link String}.
- */
- public static Date parseHttpDate(String string) {
- if (string == null) return null;
- SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_822, LOCALE);
- formatter.setTimeZone(TIMEZONE);
- try {
- return formatter.parse(string);
- } catch (ParseException exception) {
- return null;
- }
- }
-
- /**
- * Parse a {@link String} into a {@link Date} according to the ISO 8601
- * specification (2000-12-31T11:59:00Z
).
- *
- * @param string the {@link String} to parse.
- * @return a {@link Date} instance or null if the date was null or
- * if there was an error parsing the specified {@link String}.
- */
- public static Date parseIsoDate(String string) {
- if (string == null) return null;
- SimpleDateFormat formatter = new SimpleDateFormat(FORMAT_ISO, LOCALE);
- formatter.setTimeZone(TIMEZONE);
- try {
- return formatter.parse(string);
- } catch (ParseException exception) {
- return null;
- }
- }
-
- /**
- * Return the HEX representation of an array of bytes.
- *
- * @param buffer the array of bytes to convert in a HEX {@link String}.
- * @return a non-null {@link String} instance.
- */
- public static String toHexString(byte buffer[]) {
- char output[] = new char[buffer.length * 2];
- int position = 0;
- for (int x = 0; x < buffer.length; x++) {
- output[position ++] = DAVUtilities.toHexDigit(buffer[x] >> 4);
- output[position ++] = DAVUtilities.toHexDigit(buffer[x]);
- }
- return new String(output);
- }
-
- /**
- * Return the HEX representation of a long integer.
- *
- * @param number the long to convert in a HEX {@link String}.
- * @return a non-null 16-characters {@link String} instance.
- */
- public static String toHexString(long number) {
- char output[] = new char[16];
- output[0] = DAVUtilities.toHexDigit((int)(number >> 60));
- output[1] = DAVUtilities.toHexDigit((int)(number >> 56));
- output[2] = DAVUtilities.toHexDigit((int)(number >> 52));
- output[3] = DAVUtilities.toHexDigit((int)(number >> 48));
- output[4] = DAVUtilities.toHexDigit((int)(number >> 44));
- output[5] = DAVUtilities.toHexDigit((int)(number >> 40));
- output[6] = DAVUtilities.toHexDigit((int)(number >> 36));
- output[7] = DAVUtilities.toHexDigit((int)(number >> 32));
- output[8] = DAVUtilities.toHexDigit((int)(number >> 28));
- output[9] = DAVUtilities.toHexDigit((int)(number >> 24));
- output[10] = DAVUtilities.toHexDigit((int)(number >> 20));
- output[11] = DAVUtilities.toHexDigit((int)(number >> 16));
- output[12] = DAVUtilities.toHexDigit((int)(number >> 12));
- output[13] = DAVUtilities.toHexDigit((int)(number >> 8));
- output[14] = DAVUtilities.toHexDigit((int)(number >> 4));
- output[15] = DAVUtilities.toHexDigit((int)(number));
- return new String(output);
- }
-
- /**
- * Return the HEX representation of an integer.
- *
- * @param number the int to convert in a HEX {@link String}.
- * @return a non-null 8-characters {@link String} instance.
- */
- public static String toHexString(int number) {
- char output[] = new char[8];
- output[0] = DAVUtilities.toHexDigit((int)(number >> 28));
- output[1] = DAVUtilities.toHexDigit((int)(number >> 24));
- output[2] = DAVUtilities.toHexDigit((int)(number >> 20));
- output[3] = DAVUtilities.toHexDigit((int)(number >> 16));
- output[4] = DAVUtilities.toHexDigit((int)(number >> 12));
- output[5] = DAVUtilities.toHexDigit((int)(number >> 8));
- output[6] = DAVUtilities.toHexDigit((int)(number >> 4));
- output[7] = DAVUtilities.toHexDigit((int)(number));
- return new String(output);
- }
-
- /**
- * Return the HEX representation of a char.
- *
- * @param number the char to convert in a HEX {@link String}.
- * @return a non-null 4-characters {@link String} instance.
- */
- public static String toHexString(char number) {
- char output[] = new char[4];
- output[0] = DAVUtilities.toHexDigit((int)(number >> 12));
- output[1] = DAVUtilities.toHexDigit((int)(number >> 8));
- output[2] = DAVUtilities.toHexDigit((int)(number >> 4));
- output[3] = DAVUtilities.toHexDigit((int)(number));
- return new String(output);
- }
-
- /**
- * Return the HEX representation of a byte.
- *
- * @param number the byte to convert in a HEX {@link String}.
- * @return a non-null 2-characters {@link String} instance.
- */
- public static String toHexString(byte number) {
- char output[] = new char[2];
- output[0] = DAVUtilities.toHexDigit((int)(number >> 4));
- output[1] = DAVUtilities.toHexDigit((int)(number));
- return new String(output);
- }
-
- /**
- * Return the single digit character representing the HEX encoding of
- * the lower four bits of a given integer.
- */
- private static char toHexDigit(int number) {
- switch (number & 0x0F) {
- case 0x00: return '0';
- case 0x01: return '1';
- case 0x02: return '2';
- case 0x03: return '3';
- case 0x04: return '4';
- case 0x05: return '5';
- case 0x06: return '6';
- case 0x07: return '7';
- case 0x08: return '8';
- case 0x09: return '9';
- case 0x0A: return 'A';
- case 0x0B: return 'B';
- case 0x0C: return 'C';
- case 0x0D: return 'D';
- case 0x0E: return 'E';
- case 0x0F: return 'F';
- }
- String message = "Invalid HEX digit " + Integer.toHexString(number);
- throw new IllegalArgumentException(message);
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/XMLRepository.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/XMLRepository.java
deleted file mode 100644
index 57d34c6dc..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/XMLRepository.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav;
-
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-
-/**
- * A {@link DAVRepository} instance enforcing all {@link DAVResource}s to
- * be XML files.
- *
- * @author Pier Fumagalli
- */
-public class XMLRepository extends DAVRepository {
-
- /**
- * Create a new {@link XMLRepository} instance.
- */
- public XMLRepository(File root)
- throws IOException {
- super(root);
- }
-
- /**
- * Return the {@link DAVResource} associated with a {@link URI}.
- */
- public DAVResource getResource(URI uri)
- throws IOException {
- return new XMLResource(this, super.getResource(uri));
- }
-
- /**
- * A simple {@link DAVResource} extension enforcing XML writes.
- */
- private static final class XMLResource extends DAVResource {
-
- /**
- * Create a new {@link XMLResource} instance.
- */
- public XMLResource(XMLRepository repository, DAVResource resource) {
- super(repository, resource.getFile());
- }
-
- /**
- * Override the MIME Content-Type to text/xml
for
- * normal resources.
- */
- public String getContentType() {
- if (this.isResource()) return "text/xml";
- return super.getContentType();
- }
-
- /**
- * Return a {@link DAVOutputStream} enforcing XML formatted data.
- */
- public DAVOutputStream write() {
- return new XMLOutputStream(this);
- }
- }
-
- /**
- * A simple {@link DAVOutputStream} enforcing XML formatted data.
- */
- private static final class XMLOutputStream extends DAVOutputStream {
-
- /**
- * Create a new {@link XMLOutputStream} instance.
- */
- protected XMLOutputStream(XMLResource resource) {
- super(resource);
- }
-
- /**
- * Ensure that whatever is in the temporary file is XML.
- */
- protected void rename(File temporary, File original)
- throws IOException {
- try {
- SAXParserFactory factory = SAXParserFactory.newInstance();
- factory.setNamespaceAware(true);
- factory.setValidating(false);
- SAXParser parser = factory.newSAXParser();
- parser.parse(temporary, new DefaultHandler());
- super.rename(temporary, original);
- } catch (ParserConfigurationException exception) {
- throw new DAVException(500, "JAXP parser error", exception);
- } catch (SAXException exception) {
- throw new DAVException(415, "Error parsing data", exception);
- }
- }
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/COPY.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/COPY.java
deleted file mode 100644
index c598bdc23..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/COPY.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav.methods;
-
-import it.could.webdav.DAVException;
-import it.could.webdav.DAVMethod;
-import it.could.webdav.DAVMultiStatus;
-import it.could.webdav.DAVResource;
-import it.could.webdav.DAVTransaction;
-
-import java.io.IOException;
-import java.net.URI;
-
-
-/**
- * WebDAV
- * COPY
metohd implementation.
- *
- * @author Pier Fumagalli
- */
-public class COPY implements DAVMethod {
-
- /**
- * Create a new {@link COPY} instance.
- */
- public COPY() {
- super();
- }
-
- /**
- * Process the COPY
method.
- */
- public void process(DAVTransaction transaction, DAVResource resource)
- throws IOException {
-
- URI target = transaction.getDestination();
- if (target == null) throw new DAVException(412, "No destination");
- DAVResource dest = resource.getRepository().getResource(target);
-
- int depth = transaction.getDepth();
- boolean recursive = false;
- if (depth == 0) {
- recursive = false;
- } else if (depth == DAVTransaction.INFINITY) {
- recursive = true;
- } else {
- throw new DAVException(412, "Invalid Depth specified");
- }
-
- try {
- resource.copy(dest, transaction.getOverwrite(), recursive);
- transaction.setStatus(transaction.getOverwrite() ? 204 : 201);
- } catch (DAVMultiStatus multistatus) {
- multistatus.write(transaction);
- }
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/DELETE.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/DELETE.java
deleted file mode 100644
index 37192a8ee..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/DELETE.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav.methods;
-
-import it.could.webdav.DAVMethod;
-import it.could.webdav.DAVMultiStatus;
-import it.could.webdav.DAVResource;
-import it.could.webdav.DAVTransaction;
-
-import java.io.IOException;
-
-
-/**
- * WebDAV
- * DELETE
metohd implementation.
- *
- * @author Pier Fumagalli
- */
-public class DELETE implements DAVMethod {
-
- /**
- * Create a new {@link DELETE} instance.
- */
- public DELETE() {
- super();
- }
-
- /**
- * Process the DELETE
method.
- */
- public void process(DAVTransaction transaction, DAVResource resource)
- throws IOException {
- try {
- resource.delete();
- transaction.setStatus(204);
- } catch (DAVMultiStatus multistatus) {
- multistatus.write(transaction);
- }
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/GET.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/GET.java
deleted file mode 100644
index e7dc3c66b..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/GET.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav.methods;
-
-import it.could.webdav.DAVInputStream;
-import it.could.webdav.DAVResource;
-import it.could.webdav.DAVTransaction;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.TreeSet;
-
-
-/**
- * HTTP
- * GET
metohd implementation.
- *
- * @author Pier Fumagalli
- */
-public class GET extends HEAD {
-
- /** The encoding charset to repsesent collections.
*/
- public static final String ENCODING = "UTF-8";
-
- /** The mime type that {@link GET} will use serving collections.
*/
- public static final String COLLECTION_MIME_TYPE = "text/html ;charset=\""
- + ENCODING + "\"";
-
- /**
- * Create a new {@link GET} instance.
- */
- public GET() {
- super();
- }
-
- /**
- * Process the GET
method.
- */
- public void process(DAVTransaction transaction, DAVResource resource)
- throws IOException {
- super.process(transaction, resource);
-
- final String originalPath = transaction.getOriginalPath();
- final String normalizedPath = transaction.getNormalizedPath();
- final String current;
- final String parent;
- if (originalPath.equals(normalizedPath)) {
- final String relativePath = resource.getRelativePath();
- if (relativePath.equals("")) {
- current = transaction.lookup(resource).toASCIIString();
- } else {
- current = relativePath;
- }
- parent = "./";
- } else {
- current = "./";
- parent = "../";
- }
-
- if (resource.isCollection()) {
- transaction.setHeader( "Content-Disposition", "inline; filename=\"index.html\"");
- PrintWriter out = transaction.write(ENCODING);
- String path = resource.getRelativePath();
- out.println("");
- out.println("");
- out.println("Collection: /" + path + "");
- out.println("");
- out.println("");
- out.println("Collection: /" + path + "
");
- out.println("");
- out.println("");
- }
-
- /* Process the children (in two sorted sets, for nice ordering) */
- Set resources = new TreeSet();
- Set collections = new TreeSet();
- Iterator iterator = resource.getChildren();
- while (iterator.hasNext()) {
- final DAVResource child = (DAVResource) iterator.next();
- final StringBuffer buffer = new StringBuffer();
- final String childPath = child.getDisplayName();
- buffer.append("- ");
- buffer.append(childPath);
- buffer.append("
");
- if (child.isCollection()) {
- collections.add(buffer.toString());
- } else {
- resources.add(buffer.toString());
- }
- }
-
- /* Spit out the collections first and the resources then */
- for (Iterator i = collections.iterator(); i.hasNext(); )
- out.println(i.next());
- for (Iterator i = resources.iterator(); i.hasNext(); )
- out.println(i.next());
-
- out.println("
");
- out.println("");
- out.println("");
- out.flush();
- return;
- }
-
- /* Processing a normal resource request */
- OutputStream out = transaction.write();
- DAVInputStream in = resource.read();
- byte buffer[] = new byte[4096];
- int k = -1;
- while ((k = in.read(buffer)) != -1) out.write(buffer, 0, k);
- in.close();
- out.flush();
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/HEAD.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/HEAD.java
deleted file mode 100644
index 029437f12..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/HEAD.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav.methods;
-
-import it.could.webdav.DAVException;
-import it.could.webdav.DAVMethod;
-import it.could.webdav.DAVNotModified;
-import it.could.webdav.DAVResource;
-import it.could.webdav.DAVTransaction;
-import it.could.webdav.DAVUtilities;
-
-import java.io.IOException;
-import java.util.Date;
-
-
-/**
- * HTTP
- * HEAD
metohd implementation.
- *
- * @author Pier Fumagalli
- */
-public class HEAD implements DAVMethod {
-
- /**
- * Create a new {@link HEAD} instance.
- */
- public HEAD() {
- super();
- }
-
- /**
- * Process the HEAD
method.
- */
- public void process(DAVTransaction transaction, DAVResource resource)
- throws IOException {
- /* Check if we have to force a resource not found or a redirection */
- if (resource.isNull())
- throw new DAVException(404, "Not found", resource);
-
- /* Check if this is a conditional (processable only for resources) */
- Date ifmod = transaction.getIfModifiedSince();
- Date lsmod = resource.getLastModified();
- if (resource.isResource() && (ifmod != null) && (lsmod != null)) {
- /* HTTP doesn't send milliseconds, but Java does, so, reset them */
- lsmod = new Date(((long)(lsmod.getTime() / 1000)) * 1000);
- if (!ifmod.before(lsmod)) throw new DAVNotModified(resource);
- }
-
- /* Get the headers of this method */
- String ctyp = resource.getContentType();
- String etag = resource.getEntityTag();
- String lmod = DAVUtilities.formatHttpDate(resource.getLastModified());
- String clen = DAVUtilities.formatNumber(resource.getContentLength());
-
- /* Set the normal headers that are required for a GET */
- if (resource.isCollection()) {
- transaction.setContentType(GET.COLLECTION_MIME_TYPE);
- } else if (ctyp != null) {
- transaction.setContentType(ctyp);
- }
- if (etag != null) transaction.setHeader("ETag", etag);
- if (lmod != null) transaction.setHeader("Last-Modified", lmod);
- if (clen != null) transaction.setHeader("Content-Length", clen);
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/MKCOL.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/MKCOL.java
deleted file mode 100644
index 167d4a167..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/MKCOL.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav.methods;
-
-import it.could.webdav.DAVException;
-import it.could.webdav.DAVMethod;
-import it.could.webdav.DAVResource;
-import it.could.webdav.DAVTransaction;
-
-import java.io.IOException;
-
-
-/**
- * WebDAV
- * MKCOL
metohd implementation.
- *
- * @author Pier Fumagalli
- */
-public class MKCOL implements DAVMethod {
-
- /**
- * Create a new {@link MKCOL} instance.
- */
- public MKCOL() {
- super();
- }
-
- /**
- * Process the MKCOL
method.
- */
- public void process(DAVTransaction transaction, DAVResource resource)
- throws IOException {
-
- /* Unsupported media type, we don't want content */
- if (transaction.hasRequestBody()) {
- throw new DAVException (415, "No request body allowed in request");
- }
-
- /* Create the collection */
- resource.makeCollection();
- transaction.setStatus(201);
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/MOVE.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/MOVE.java
deleted file mode 100644
index 672636beb..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/MOVE.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav.methods;
-
-import it.could.webdav.DAVException;
-import it.could.webdav.DAVMethod;
-import it.could.webdav.DAVMultiStatus;
-import it.could.webdav.DAVResource;
-import it.could.webdav.DAVTransaction;
-
-import java.io.IOException;
-import java.net.URI;
-
-
-/**
- * WebDAV
- * MOVE
metohd implementation.
- *
- * @author Pier Fumagalli
- */
-public class MOVE implements DAVMethod {
-
- /**
- * Create a new {@link MOVE} instance.
- */
- public MOVE() {
- super();
- }
-
- /**
- * Process the MOVE
method.
- */
- public void process(DAVTransaction transaction, DAVResource resource)
- throws IOException {
- URI target = transaction.getDestination();
- if (target == null) throw new DAVException(412, "No destination");
- DAVResource dest = resource.getRepository().getResource(target);
-
- int depth = transaction.getDepth();
- boolean recursive = false;
- if (depth == 0) {
- recursive = false;
- } else if (depth == DAVTransaction.INFINITY) {
- recursive = true;
- } else {
- throw new DAVException(412, "Invalid Depth specified");
- }
-
- try {
- int status;
- if(! dest.isNull() && ! transaction.getOverwrite()) {
- status = 412; // MOVE-on-existing should fail with 412
- } else {
- resource.move(dest, transaction.getOverwrite(), recursive);
- if(transaction.getOverwrite()) {
- status = 204; // No Content
- } else {
- status = 201; // Created
- }
- }
- transaction.setStatus(status);
- } catch (DAVMultiStatus multistatus) {
- multistatus.write(transaction);
- }
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/OPTIONS.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/OPTIONS.java
deleted file mode 100644
index 0228c09dc..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/OPTIONS.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav.methods;
-
-import it.could.webdav.DAVMethod;
-import it.could.webdav.DAVProcessor;
-import it.could.webdav.DAVResource;
-import it.could.webdav.DAVTransaction;
-
-import java.io.IOException;
-
-
-/**
- * HTTP
- * OPTIONS
metohd implementation.
- *
- * @author Pier Fumagalli
- */
-public class OPTIONS implements DAVMethod {
-
- /**
- * Create a new {@link OPTIONS} instance.
- */
- public OPTIONS() {
- super();
- }
-
- /**
- * Process the OPTIONS
method.
- */
- public void process(DAVTransaction transaction, DAVResource resource)
- throws IOException {
- transaction.setHeader("Content-Type", resource.getContentType());
- transaction.setHeader("Allow", DAVProcessor.METHODS);
- transaction.setStatus(200);
- }
-
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/PROPFIND.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/PROPFIND.java
deleted file mode 100644
index 3854f20f0..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/PROPFIND.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav.methods;
-
-import it.could.webdav.DAVException;
-import it.could.webdav.DAVMethod;
-import it.could.webdav.DAVResource;
-import it.could.webdav.DAVTransaction;
-import it.could.webdav.DAVUtilities;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.Iterator;
-
-
-/**
- * WebDAV
- * PROPFIND
metohd implementation.
- *
- * @author Pier Fumagalli
- */
-public class PROPFIND implements DAVMethod {
-
- /**
- * Create a new {@link PROPFIND} instance.
- */
- public PROPFIND() {
- super();
- }
-
- /**
- * Process the PROPFIND
method.
- */
- public void process(DAVTransaction transaction, DAVResource resource)
- throws IOException {
- /* Check if we have to force a resource not found or a redirection */
- if (resource.isNull())
- throw new DAVException(404, "Not found", resource);
-
- /* Check depth */
- int depth = transaction.getDepth();
- if (depth > 1) new DAVException(403, "Invalid depth");
-
- /* What to do on a collection resource */
- transaction.setStatus(207);
- transaction.setContentType("text/xml; charset=\"UTF-8\"");
- PrintWriter out = transaction.write("UTF-8");
-
- /* Output the XML declaration and the root document tag */
- out.print("");
- out.println("");
-
- /* Process this resource's property (always) */
- this.process(transaction, out, resource);
-
- /* Process this resource's children (if required) */
- if (resource.isCollection() && (depth > 0)) {
- Iterator children = resource.getChildren();
- while (children.hasNext()) {
- DAVResource child = (DAVResource) children.next();
- this.process(transaction, out, child);
- }
- }
-
- /* Close up the XML Multi-Status response */
- out.println("");
- out.flush();
- }
-
- private void process(DAVTransaction txn, PrintWriter out, DAVResource res) {
- /* The href of the resource is only the absolute path */
- out.println(" ");
- out.println(" " + txn.lookup(res).getPath() + "");
- out.println(" ");
- out.println(" ");
-
- /* Figure out what we're dealing with here */
- if (res.isCollection()) {
- this.process(out, "resourcetype", "");
- }
- this.process(out, "getcontenttype", res.getContentType());
-
- this.process(out, "getetag", res.getEntityTag());
- String date = DAVUtilities.formatIsoDate(res.getCreationDate());
- this.process(out, "creationdate", date);
- String lmod = DAVUtilities.formatHttpDate(res.getLastModified());
- this.process(out, "getlastmodified", lmod);
- String clen = DAVUtilities.formatNumber(res.getContentLength());
- this.process(out, "getcontentlength", clen);
-
- out.println(" ");
- out.println(" HTTP/1.1 200 OK");
- out.println(" ");
- out.println(" ");
- }
-
- private void process(PrintWriter out, String name, String value) {
- if (value == null) return;
- out.print(" ");
- out.print(value);
- out.print("");
- }
-
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/PROPPATCH.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/PROPPATCH.java
deleted file mode 100644
index fbddd0e84..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/PROPPATCH.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav.methods;
-
-import it.could.webdav.DAVException;
-import it.could.webdav.DAVMethod;
-import it.could.webdav.DAVResource;
-import it.could.webdav.DAVTransaction;
-
-import java.io.IOException;
-
-
-/**
- * WebDAV
- * PROPPATCH
metohd implementation.
- *
- * As this servlet does not handle the creation of custom properties, this
- * method will always fail with a 403
(Forbidden).
- *
- * @author Pier Fumagalli
- */
-public class PROPPATCH implements DAVMethod {
-
- /**
- * Create a new {@link PROPPATCH} instance.
- */
- public PROPPATCH() {
- super();
- }
-
- /**
- * Process the PROPPATCH
method.
- *
- * As this servlet does not handle the creation of custom properties,
- * this method will always fail with a 403
(Forbidden).
- */
- public void process(DAVTransaction transaction, DAVResource resource)
- throws IOException {
- throw new DAVException(403, "All properties are immutable");
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/PUT.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/PUT.java
deleted file mode 100644
index fb995e69d..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/PUT.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav.methods;
-
-import it.could.webdav.DAVException;
-import it.could.webdav.DAVMethod;
-import it.could.webdav.DAVOutputStream;
-import it.could.webdav.DAVResource;
-import it.could.webdav.DAVTransaction;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-
-/**
- * WebDAV
- * PUT
metohd implementation.
- *
- * @author Pier Fumagalli
- */
-public class PUT implements DAVMethod {
-
- /**
- * Create a new {@link PUT} instance.
- */
- public PUT() {
- super();
- }
-
- /**
- * Process the PUT
method.
- */
- public void process(DAVTransaction transaction, DAVResource resource)
- throws IOException {
- /*
- * The HTTP status code will depend on the existance of the resource:
- * if not found: HTTP/1.1 201 Created
- * if existing: HTTP/1.1 204 No Content
- */
- transaction.setStatus(resource.isNull()? 201: 204);
-
- /* Open the streams for reading and writing */
- InputStream in = transaction.read();
- if (in == null) throw new DAVException(411, "Content-Length required");
- DAVOutputStream out = resource.write();
-
- /* Write the content from the PUT to the specified resource */
- try {
- byte buffer[] = new byte[4096];
- int k = -1;
- while ((k = in.read(buffer)) != -1) out.write(buffer, 0, k);
- in.close();
- out.close();
- } finally {
- out.abort();
- }
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/package.html b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/package.html
deleted file mode 100644
index f74f01889..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/methods/package.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
- Could.IT WebDAV Servlet
-
-
-
- This package contains the implementation of all Level 1
- WebDAV
- methods provided by this framework.
-
-
-
\ No newline at end of file
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/package.html b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/package.html
deleted file mode 100644
index 1354f9f33..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/package.html
+++ /dev/null
@@ -1,134 +0,0 @@
-
-
- Could.IT WebDAV Servlet
-
-
-
- This package contains a minimal
- Servlet
- based implementation of the
- WebDAV
- specification.
-
-
- This implementation does not in any way try to replace or extend the
- Apache Slide
- WebDAV
- implementation, but tries to provide a very light and extremely
- minimal alternative to be used in those scenarios where space is
- a constraint (the .jar
file is less than 100 kylobites),
- and advanced features are not required.
-
-
- The most visible limitations of this approach is that this
- implementation does not offer any support for the LOCK
- method (it is therefore not DAV Level 2 compliant), and that
- there limited support for properties:
-
-
- -
- The
PROPFIND
will only return the read-only
- getcontenttype
, getlastmodified
,
- getcontentlength
, getetag
and
- resourcetype
properties.
-
- -
- The
PROPPATCH
will always fail with a
- 403
Not Found error.
-
-
-
- Another important limitation is that this implementation will only and
- exclusively provide access to a {@link java.io.File} based backend.
- If you want to deploy your repository on another kind of backend (such
- as SQL databases) please look at the WebDAV implementation provided by
- Apache Slide.
-
-
- Configuration
-
- The main entry point of this implementation is defined in the
- {@link it.could.webdav.DAVServlet} class, which will handle all
- HTTP and
- WebDAV requests
- for the URI path it is configured to handle.
-
-
- To operate properly the {@link it.could.webdav.DAVServlet} class
- must be configured in the web-application's web.xml
- deployment descriptor. The relevant parts of a snippet of an example
- configuration deployment descriptor might look like the following:
-
-
-<servlet>
- <servlet-name>dav</servlet-name>
- <servlet-class>it.could.webdav.DAVServlet</servlet-class>
- <init-param>
- <param-name>rootPath</param-name>
- <param-value>dav</param-value>
- </init-param>
- <init-param>
- <param-name>xmlOnly</param-name>
- <param-value>false</param-value>
- </init-param>
- <init-param>
- <param-name>debugEnabled</param-name>
- <param-value>false</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
-</servlet>
-
-...
-
-<servlet-mapping>
- <servlet-name>dav</servlet-name>
- <url-pattern>/dav/*</url-pattern>
-</servlet-mapping>
-
-
- In this example the {@link it.could.webdav.DAVServlet} servlet
- is configured with all parameters its parameters:
-
-
- - rootPath
- -
- [required] This parameter indicates the path of the root of the
- repository.
- If the specified parameter represents a relative path, it will be
- treated as a {@link javax.servlet.ServletContext#getResource(String)
- ServletContext resource}.
- Note that if you choose to distribute your web application in a
- .war
archive, your container will have to expand it
- before intializing the {@link javax.servlet.ServletContext} as this
- this implementation requires a {@link java.io.File} based
- repository.
-
- - xmlOnly
- -
- [optional, default="
false
"] This parameter
- will instruct the {@link it.could.webdav.DAVServlet} to create
- a very specialized version of the repository accepting only
- well-formed
- XML resources and collections.
- Note that when set to true
this implementation will rely
- on the JAXP specification
- to access a XML parser used to verify the PUT
content.
-
- - debugEnabled
- -
- [optional, default="
false
"] This parameter
- will instruct the {@link it.could.webdav.DAVServlet} to log
- unimportant debugging information (such as the methods called by the
- client) in the {@link javax.servlet.ServletContext#log(String) context
- log}.
-
-
-
- The configured {@link it.could.webdav.DAVServlet} will then have
- to be mapped to a path, and in the example above, every request for
- any URL beginning in /dav/
will be handled by this
- implementation, with a repository rooted in the /dav/
- directory of the web application.
-
-
-
\ No newline at end of file
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/replication/DAVReplica.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/replication/DAVReplica.java
deleted file mode 100644
index 56fc2e499..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/replication/DAVReplica.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav.replication;
-
-import it.could.util.StreamTools;
-import it.could.util.http.WebDavClient;
-import it.could.util.location.Location;
-import it.could.webdav.DAVListener;
-import it.could.webdav.DAVLogger;
-import it.could.webdav.DAVRepository;
-import it.could.webdav.DAVResource;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-/**
- * TODO: Document this class.
- *
- * @author Pier Fumagalli
- */
-public class DAVReplica extends Thread implements DAVListener {
-
- private static final int SYNCHRONIZE = -1;
-
- private final DAVRepository repository;
- private final DAVLogger logger;
- private final Location location;
- private final List actions = new ArrayList();
-
- public DAVReplica(DAVRepository repository, Location location,
- DAVLogger logger)
- throws IOException {
- this.location = new WebDavClient(location).getLocation();
- this.repository = repository;
- this.logger = logger;
- this.start();
- }
-
- public void synchronize()
- throws IOException {
- this.logger.log("Scheduling full synchronization");
- this.notify(this.repository.getResource((String)null), SYNCHRONIZE);
- }
-
- public void notify(DAVResource resource, int event) {
- this.logger.debug("Event for \"" + resource.getRelativePath() + "\"");
- if (resource.getRepository() != this.repository) return;
- synchronized (this.actions) {
- this.actions.add(new Action(resource, event));
- this.actions.notify();
- }
- }
-
- public void run() {
- this.logger.debug("Starting background replica thread on " + location);
- while (true) try {
- final DAVReplica.Action array[];
- synchronized(this.actions) {
- try {
- if (this.actions.isEmpty()) this.actions.wait();
- final int s = this.actions.size();
- array = (Action []) this.actions.toArray(new Action[s]);
- this.actions.clear();
- } catch (InterruptedException exception) {
- this.logger.debug("Exiting background replica thread");
- return;
- }
- }
-
- for (int x = 0; x < array.length; x ++) try {
- this.replicate(array[x]);
- } catch (Throwable throwable) {
- final String path = array[x].resource.getRelativePath();
- final String message = "Error synchronizing resource " + path;
- this.logger.log(message, throwable);
- }
- } catch (Throwable throwable) {
- this.logger.log("Replica thread attempted suicide", throwable);
- }
- }
-
- private void replicate(DAVReplica.Action action) {
- final DAVResource resource = action.resource;
-
- if (action.event == SYNCHRONIZE) {
- this.synchronize(resource);
-
- } else try {
- final String path = resource.getParent().getRelativePath();
- final Location location = this.location.resolve(path);
- final WebDavClient client = new WebDavClient(location);
- final String child = resource.getName();
-
- switch(action.event) {
- case RESOURCE_CREATED:
- case RESOURCE_MODIFIED:
- this.logger.debug("Putting resource " + path);
- this.put(resource, client);
- break;
- case RESOURCE_REMOVED:
- case COLLECTION_REMOVED:
- this.logger.debug("Deleting resource " + path);
- client.delete(child);
- break;
- case COLLECTION_CREATED:
- this.logger.debug("Creating collection " + path);
- client.mkcol(child);
- break;
- }
- } catch (IOException exception) {
- String message = "Error replicating " + resource.getRelativePath();
- this.logger.log(message, exception);
- }
- }
-
- private void put(DAVResource resource, WebDavClient client)
- throws IOException {
- final String name = resource.getName();
- final long length = resource.getContentLength().longValue();
- final OutputStream output = client.put(name, length);
- final InputStream input = resource.read();
- StreamTools.copy(input, output);
- }
-
- private void synchronize(DAVResource resource) {
- /* Figure out the path of the resource */
- final String path = resource.getRelativePath();
-
- /* If it's a file or null, just skip the whole thing */
- if (! resource.isCollection()) {
- this.logger.log("Synchronization on non-collection " + path);
- return;
- }
-
- /* Open a webdav client to the collection to synchronize */
- this.logger.log("Synchronizing collection " + path);
- final WebDavClient client;
- try {
- final Location location = this.location.resolve(path);
- client = new WebDavClient(location);
- } catch (IOException exception) {
- this.logger.log("Error creating WebDAV client", exception);
- return;
- }
-
- /* Create a list of all children from the DAV client */
- final Set children = new HashSet();
- for (Iterator iter = client.iterator(); iter.hasNext(); )
- children.add(iter.next());
-
- /* Process all resource children one by one and ensure they exist */
- for (Iterator iter = resource.getChildren(); iter.hasNext(); ) {
- final DAVResource child = (DAVResource) iter.next();
- final String name = child.getName();
-
- /* Remove this from the resources that will be removed later */
- children.remove(name);
-
- /* If the client doesn't have this child, add it to the replica */
- if (! client.hasChild(name)) try {
- if (child.isCollection()) {
- this.logger.debug("Client doesn't have collection " + name);
- client.mkcol(name);
- this.synchronize(child);
-
- } else {
- this.logger.debug("Client doesn't have resource " + name);
- this.put(child, client);
- }
- } catch (IOException exception) {
- this.logger.log("Error creating new child " + name, exception);
-
- /* If this child is a collection, it must be a collection on dav */
- } else if (child.isCollection()) try {
- if (!client.isCollection(name)) {
- this.logger.debug("Recreating collection " + name);
- client.delete(name).mkcol(name);
- }
- this.synchronize(child);
- } catch (IOException exception) {
- this.logger.log("Error creating collection " + name, exception);
-
- /* Ok, the resource is a normal one, verify size and timestamp */
- } else try {
- final Date rlast = child.getLastModified();
- final Date dlast = client.getLastModified(name);
- if ((rlast != null) && (rlast.equals(dlast))) {
- final Long rlen = child.getContentLength();
- final long dlen = client.getContentLength(name);
- if ((rlen == null) || (rlen.longValue() != dlen)) {
- this.logger.debug("Resending resource " + name);
- this.put(child, client.delete(name));
- }
- }
- } catch (IOException exception) {
- this.logger.log("Error resending resource " + name, exception);
- }
- }
-
- /* Any other child that was not removed above, will go away now! */
- for (Iterator iter = children.iterator(); iter.hasNext(); ) {
- final String name = (String) iter.next();
- try {
- this.logger.debug("Removing leftovers " + name);
- client.delete(name);
- } catch (IOException exception) {
- this.logger.log("Error removing left over " + name, exception);
- }
- }
- }
-
- private static final class Action {
- final DAVResource resource;
- final int event;
-
- private Action(DAVResource resource, int event) {
- this.resource = resource;
- this.event = event;
- }
- }
-}
\ No newline at end of file
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/replication/DAVReplicator.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/replication/DAVReplicator.java
deleted file mode 100644
index c7de67b14..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/replication/DAVReplicator.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/* ========================================================================== *
- * Copyright (C) 2004-2006, Pier Fumagalli *
- * All rights reserved. *
- * ========================================================================== *
- * *
- * 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 . *
- * *
- * 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 it.could.webdav.replication;
-
-import it.could.util.location.Location;
-import it.could.webdav.DAVListener;
-import it.could.webdav.DAVLogger;
-import it.could.webdav.DAVRepository;
-import it.could.webdav.DAVServlet;
-
-import javax.servlet.Servlet;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.StringTokenizer;
-
-/**
- * The {@link DAVReplicator} class is a {@link DAVListener} replicating
- * all content to the WebDAV repository specified at construction.
- *
- * @author Pier Fumagalli
- */
-public class DAVReplicator extends HttpServlet {
-
- /** The {@link DAVReplica} instances managed by this.
*/
- private final List replicas = new ArrayList();
-
- /**
- * Create a new {@link DAVServlet} instance.
- */
- public DAVReplicator() {
- super();
- }
-
- /**
- * Initialize this {@link Servlet} instance.
- *
- * This servlet requires a couple of initialization parameters: the
- * first one is "repository
" indicating the name of
- * the {@link DAVServlet} in the "web.xml
" deployment
- * descriptor whose repository should be replicated.
- *
- * The second required parameter "replicas
"
- * must contain a (whitespace separated list of) URL(s) where the original
- * repository should be replicated to.
- *
- * Finally, when set to true
, the optional parameter
- * debugEnabled
will enable logging of method invocation and
- * events in the repository.
- */
- public void init(ServletConfig config)
- throws ServletException {
- /* Initialize the super, just in case, and remember the context */
- super.init(config);
-
- /* Setup logging */
- boolean debug = "true".equals(config.getInitParameter("debugEnabled"));
- DAVLogger logger = new DAVLogger(config, debug);
-
- /* Try to retrieve the WebDAV repository from the servlet context */
- final String repositoryName = config.getInitParameter("repository");
- final DAVRepository repository;
- if (repositoryName == null) {
- throw new ServletException("Parameter \"rootPath\" not specified");
- } else try {
- final String key = DAVServlet.getRepositoryKey(repositoryName);
- final ServletContext context = config.getServletContext();
- repository = (DAVRepository) context.getAttribute(key);
- if (repository == null)
- throw new ServletException("Unable to access repository from " +
- "servlet \"" + repository + "\"");
- } catch (ClassCastException exception) {
- final String message = "Class cast exception accessing repository";
- throw new ServletException(message, exception);
- }
-
- /* Access the different WebDAV replicas */
- final String replicas = config.getInitParameter("replicas");
- if (replicas == null) {
- throw new ServletException("Parameter \"replicas\" not specified");
- }
-
- try {
- final StringTokenizer tokenizer = new StringTokenizer(replicas);
- while (tokenizer.hasMoreTokens()) {
- final Location location = Location.parse(tokenizer.nextToken());
- final DAVReplica replica = new DAVReplica(repository, location,
- logger);
- logger.log("Added repository replica to \"" + location + "\"");
- repository.addListener(replica);
- this.replicas.add(replica);
- replica.synchronize();
- }
- } catch (IOException exception) {
- throw new ServletException("Error creating replica", exception);
- }
-
- /* Check that we have at least one replica in */
- if (this.replicas.size() != 0) return;
- throw new ServletException("No replicas specified for repository");
- }
-
- /**
- * Destroy {@link DAVServlet} instance interrupting all running
- * {@link DAVReplica} instances.
- */
- public void destroy() {
- for (Iterator iter = this.replicas.iterator(); iter.hasNext() ; ) {
- ((DAVReplica) iter.next()).interrupt();
- }
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/replication/package.html b/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/replication/package.html
deleted file mode 100644
index 4ca6e5c1c..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/it/could/webdav/replication/package.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
- Could.IT WebDAV Servlet
-
-
-
- This package contains a framework for maintaining fully replicated
- WebDAV
- repositories.
-
-
-
\ No newline at end of file
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/AbstractDavServerComponent.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/AbstractDavServerComponent.java
deleted file mode 100644
index c674f6b9e..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/AbstractDavServerComponent.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.maven.archiva.webdav;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * AbstractDavServerComponent
- *
- * @author Joakim Erdfelt
- * @version $Id: AbstractDavServerComponent.java 6000 2007-03-04 22:01:49Z joakime $
- */
-public abstract class AbstractDavServerComponent
- implements DavServerComponent
-{
- private List listeners;
- protected boolean useIndexHtml = false;
-
- public AbstractDavServerComponent()
- {
- listeners = new ArrayList();
- }
-
- public void addListener( DavServerListener listener )
- {
- listeners.add( listener );
- }
-
- public void removeListener( DavServerListener listener )
- {
- listeners.remove( listener );
- }
-
- protected void triggerCollectionCreated( String resource )
- {
- Iterator it = listeners.iterator();
- while ( it.hasNext() )
- {
- DavServerListener listener = (DavServerListener) it.next();
- try
- {
- listener.serverCollectionCreated( this, resource );
- }
- catch ( Exception e )
- {
- /* ignore error */
- }
- }
- }
-
- protected void triggerCollectionRemoved( String resource )
- {
- Iterator it = listeners.iterator();
- while ( it.hasNext() )
- {
- DavServerListener listener = (DavServerListener) it.next();
- try
- {
- listener.serverCollectionRemoved( this, resource );
- }
- catch ( Exception e )
- {
- /* ignore error */
- }
- }
- }
-
- protected void triggerResourceCreated( String resource )
- {
- Iterator it = listeners.iterator();
- while ( it.hasNext() )
- {
- DavServerListener listener = (DavServerListener) it.next();
- try
- {
- listener.serverResourceCreated( this, resource );
- }
- catch ( Exception e )
- {
- /* ignore error */
- }
- }
- }
-
- protected void triggerResourceRemoved( String resource )
- {
- Iterator it = listeners.iterator();
- while ( it.hasNext() )
- {
- DavServerListener listener = (DavServerListener) it.next();
- try
- {
- listener.serverResourceRemoved( this, resource );
- }
- catch ( Exception e )
- {
- /* ignore error */
- }
- }
- }
-
- protected void triggerResourceModified( String resource )
- {
- Iterator it = listeners.iterator();
- while ( it.hasNext() )
- {
- DavServerListener listener = (DavServerListener) it.next();
- try
- {
- listener.serverResourceModified( this, resource );
- }
- catch ( Exception e )
- {
- /* ignore error */
- }
- }
- }
-
- public boolean hasResource( String resource )
- {
- File rootDir = getRootDirectory();
- if ( rootDir == null )
- {
- return false;
- }
- File resourceFile = new File( rootDir, resource );
- return resourceFile.exists();
- }
-
- public boolean isUseIndexHtml()
- {
- return this.useIndexHtml;
- }
-
- public void setUseIndexHtml( boolean useIndexHtml )
- {
- this.useIndexHtml = useIndexHtml;
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavLocatorFactory.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavLocatorFactory.java
new file mode 100644
index 000000000..6ea9a9397
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavLocatorFactory.java
@@ -0,0 +1,72 @@
+package org.apache.maven.archiva.webdav;
+
+/*
+ * 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.
+ */
+
+import org.apache.jackrabbit.webdav.DavLocatorFactory;
+import org.apache.jackrabbit.webdav.DavResourceLocator;
+import org.apache.jackrabbit.util.Text;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.maven.archiva.webdav.util.RepositoryPathUtil;
+
+/**
+ * @author James William Dumay
+ */
+public class ArchivaDavLocatorFactory implements DavLocatorFactory
+{
+ public DavResourceLocator createResourceLocator(String prefix, String href)
+ {
+ // build prefix string and remove all prefixes from the given href.
+ StringBuilder b = new StringBuilder();
+ if (prefix != null && prefix.length() > 0) {
+ b.append(prefix);
+ if (!prefix.endsWith("/"))
+ {
+ b.append('/');
+ }
+ if (href.startsWith(prefix)) {
+ href = href.substring(prefix.length());
+ }
+ }
+
+ // special treatment for root item, that has no name but '/' path.
+ if (href == null || "".equals(href)) {
+ href = "/";
+ }
+
+ final String workspaceName = RepositoryPathUtil.getRepositoryName(href);
+
+ return new ArchivaDavResourceLocator(b.toString(), Text.unescape(href), workspaceName, this);
+ }
+
+ public DavResourceLocator createResourceLocator(String prefix, String workspacePath, String resourcePath)
+ {
+ return createResourceLocator(prefix, workspacePath, resourcePath, true);
+ }
+
+ public DavResourceLocator createResourceLocator(String prefix, String workspacePath,
+ String path, boolean isResourcePath)
+ {
+ final String repository = RepositoryPathUtil.getRepositoryName(path);
+ return new ArchivaDavResourceLocator(prefix, path, repository, this);
+ }
+
+
+}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResource.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResource.java
new file mode 100644
index 000000000..7d2d7f40d
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResource.java
@@ -0,0 +1,301 @@
+package org.apache.maven.archiva.webdav;
+
+/*
+ * 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.
+ */
+
+import org.apache.jackrabbit.webdav.*;
+import org.apache.jackrabbit.webdav.property.DavPropertySet;
+import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
+import org.apache.jackrabbit.webdav.property.DavProperty;
+import org.apache.jackrabbit.webdav.property.DavPropertyName;
+import org.apache.jackrabbit.webdav.io.InputContext;
+import org.apache.jackrabbit.webdav.io.OutputContext;
+import org.apache.jackrabbit.webdav.lock.*;
+import org.apache.jackrabbit.util.Text;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.FileUtils;
+import org.apache.maven.archiva.webdav.util.MimeTypes;
+import org.apache.maven.archiva.webdav.util.IndexWriter;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+import java.util.Date;
+import java.io.*;
+
+/**
+ * @author James William Dumay
+ */
+public class ArchivaDavResource implements DavResource
+{
+ private final MimeTypes mimeTypes;
+
+ private final DavResourceLocator locator;
+
+ private final DavResourceFactory factory;
+
+ private final DavSession session;
+
+ private final File localResource;
+
+ private final String logicalResource;
+
+ private static final String METHODS = "OPTIONS, GET, HEAD, POST, TRACE, PROPFIND, PROPPATCH, MKCOL, COPY, PUT, DELETE, MOVE";
+
+ private static final String COMPLIANCE_CLASS = "1";
+
+ private DavPropertySet properties;
+
+ public ArchivaDavResource(String localResource, String logicalResource, MimeTypes mimeTypes, DavResourceLocator locator, DavResourceFactory factory, DavSession session)
+ {
+ this.mimeTypes = mimeTypes;
+ this.localResource = new File(localResource);
+ this.logicalResource = logicalResource;
+ this.locator = locator;
+ this.factory = factory;
+ this.session = session;
+ this.properties = new DavPropertySet();
+ }
+
+ public String getContentType()
+ {
+ return mimeTypes.getMimeType(localResource.getName());
+ }
+
+ public String getComplianceClass()
+ {
+ return COMPLIANCE_CLASS;
+ }
+
+ public String getSupportedMethods()
+ {
+ return METHODS;
+ }
+
+ public boolean exists()
+ {
+ return localResource.exists();
+ }
+
+ public boolean isCollection()
+ {
+ return localResource.isDirectory();
+ }
+
+ public String getDisplayName()
+ {
+ String resPath = getResourcePath();
+ return (resPath != null) ? Text.getName(resPath) : resPath;
+ }
+
+ public DavResourceLocator getLocator()
+ {
+ return locator;
+ }
+
+ public String getResourcePath()
+ {
+ return locator.getResourcePath();
+ }
+
+ public String getHref()
+ {
+ return locator.getHref(isCollection());
+ }
+
+ public long getModificationTime()
+ {
+ return localResource.lastModified();
+ }
+
+ public long getContentLength()
+ {
+ return localResource.length();
+ }
+
+ public void spool(OutputContext outputContext) throws IOException
+ {
+ if (!isCollection())
+ {
+ IOUtils.copy(new FileInputStream(localResource), outputContext.getOutputStream());
+ }
+ else
+ {
+ IndexWriter writer = new IndexWriter(this, localResource, logicalResource);
+ writer.write(outputContext);
+ }
+ }
+
+ public DavPropertyName[] getPropertyNames()
+ {
+ return new DavPropertyName[0];
+ }
+
+ public DavProperty getProperty(DavPropertyName name)
+ {
+ return null;
+ }
+
+ public DavPropertySet getProperties()
+ {
+ return properties;
+ }
+
+ public void setProperty(DavProperty property) throws DavException
+ {
+ }
+
+ public void removeProperty(DavPropertyName propertyName) throws DavException
+ {
+ }
+
+ public MultiStatusResponse alterProperties(DavPropertySet setProperties, DavPropertyNameSet removePropertyNames) throws DavException
+ {
+ return null;
+ }
+
+ public MultiStatusResponse alterProperties(List changeList) throws DavException
+ {
+ return null;
+ }
+
+ public DavResource getCollection()
+ {
+ DavResource parent = null;
+ if (getResourcePath() != null && !getResourcePath().equals("/")) {
+ String parentPath = Text.getRelativeParent(getResourcePath(), 1);
+ if (parentPath.equals("")) {
+ parentPath = "/";
+ }
+ DavResourceLocator parentloc = locator.getFactory().createResourceLocator(locator.getPrefix(), locator.getWorkspacePath(), parentPath);
+ try {
+ parent = factory.createResource(parentloc, session);
+ } catch (DavException e) {
+ // should not occur
+ }
+ }
+ return parent;
+ }
+
+ public void addMember(DavResource resource, InputContext inputContext) throws DavException
+ {
+ File localFile = new File(localResource, resource.getDisplayName());
+ if (!resource.isCollection() && isCollection() && inputContext.hasStream()) //New File
+ {
+ boolean deleteFile = false;
+ FileOutputStream stream = null;
+ try
+ {
+ stream = new FileOutputStream(localFile);
+ IOUtils.copy(inputContext.getInputStream(), stream);
+ if (inputContext.getContentLength() != localFile.length())
+ {
+ deleteFile = true;
+ throw new DavException(HttpServletResponse.SC_BAD_REQUEST, "Content Header length was "
+ + inputContext.getContentLength() + " but was " + localFile.length());
+ }
+ }
+ catch (IOException e)
+ {
+ throw new DavException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
+ }
+ finally
+ {
+ IOUtils.closeQuietly(stream);
+ if (deleteFile)
+ {
+ FileUtils.deleteQuietly(localFile);
+ }
+ }
+ }
+ else if (resource.isCollection() && isCollection()) //New directory
+ {
+ localFile.mkdir();
+ }
+ else
+ {
+ throw new DavException(HttpServletResponse.SC_BAD_REQUEST, "Could not write member "
+ + resource.getResourcePath() + " at " + getResourcePath());
+ }
+ }
+
+ public DavResourceIterator getMembers()
+ {
+ return null;
+ }
+
+ public void removeMember(DavResource member) throws DavException
+ {
+ }
+
+ public void move(DavResource destination) throws DavException
+ {
+ }
+
+ public void copy(DavResource destination, boolean shallow) throws DavException
+ {
+ }
+
+ public boolean isLockable(Type type, Scope scope)
+ {
+ return false;
+ }
+
+ public boolean hasLock(Type type, Scope scope)
+ {
+ return false;
+ }
+
+ public ActiveLock getLock(Type type, Scope scope)
+ {
+ return null;
+ }
+
+ public ActiveLock[] getLocks()
+ {
+ return new ActiveLock[0];
+ }
+
+ public ActiveLock lock(LockInfo reqLockInfo) throws DavException
+ {
+ return null;
+ }
+
+ public ActiveLock refreshLock(LockInfo reqLockInfo, String lockToken) throws DavException
+ {
+ return null;
+ }
+
+ public void unlock(String lockToken) throws DavException
+ {
+ }
+
+ public void addLockManager(LockManager lockmgr)
+ {
+ }
+
+ public DavResourceFactory getFactory()
+ {
+ return factory;
+ }
+
+ public DavSession getSession()
+ {
+ return session;
+ }
+}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java
new file mode 100644
index 000000000..f5016f187
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java
@@ -0,0 +1,497 @@
+package org.apache.maven.archiva.webdav;
+
+/*
+ * 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.
+ */
+
+import com.opensymphony.xwork.ActionContext;
+import org.apache.jackrabbit.webdav.*;
+import org.apache.maven.archiva.repository.ManagedRepositoryContent;
+import org.apache.maven.archiva.repository.RepositoryNotFoundException;
+import org.apache.maven.archiva.repository.RepositoryException;
+import org.apache.maven.archiva.repository.RepositoryContentFactory;
+import org.apache.maven.archiva.repository.layout.LayoutException;
+import org.apache.maven.archiva.repository.content.RepositoryRequest;
+import org.apache.maven.archiva.repository.audit.AuditListener;
+import org.apache.maven.archiva.repository.audit.Auditable;
+import org.apache.maven.archiva.repository.audit.AuditEvent;
+import org.apache.maven.archiva.repository.metadata.MetadataTools;
+import org.apache.maven.archiva.repository.metadata.RepositoryMetadataException;
+import org.apache.maven.archiva.webdav.util.WebdavMethodUtil;
+import org.apache.maven.archiva.webdav.util.MimeTypes;
+import org.apache.maven.archiva.webdav.util.RepositoryPathUtil;
+import org.apache.maven.archiva.proxy.RepositoryProxyConnectors;
+import org.apache.maven.archiva.common.utils.PathUtil;
+import org.apache.maven.archiva.model.ArtifactReference;
+import org.apache.maven.archiva.model.ProjectReference;
+import org.apache.maven.archiva.model.VersionedReference;
+import org.apache.maven.archiva.policies.ProxyDownloadException;
+import org.apache.maven.archiva.security.ArchivaXworkUser;
+import org.apache.maven.model.DistributionManagement;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Relocation;
+import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletException;
+import java.util.ArrayList;
+import java.util.List;
+import java.io.*;
+
+/**
+ * @author James William Dumay
+ * @plexus.component role="org.apache.maven.archiva.webdav.ArchivaDavResourceFactory"
+ */
+public class ArchivaDavResourceFactory implements DavResourceFactory, Auditable
+{
+ private Logger log = LoggerFactory.getLogger(ArchivaDavResourceFactory.class);
+
+ /**
+ * @plexus.requirement role="org.apache.maven.archiva.repository.audit.AuditListener"
+ */
+ private List auditListeners = new ArrayList();
+
+ /**
+ * @plexus.requirement
+ */
+ private RepositoryContentFactory repositoryFactory;
+
+ /**
+ * @plexus.requirement
+ */
+ private RepositoryRequest repositoryRequest;
+
+ /**
+ * @plexus.requirement role-hint="default"
+ */
+ private RepositoryProxyConnectors connectors;
+
+ /**
+ * @plexus.requirement
+ */
+ private MetadataTools metadataTools;
+
+ /**
+ * @plexus.requirement
+ */
+ private MimeTypes mimeTypes;
+
+ public DavResource createResource(final DavResourceLocator locator, final DavServletRequest request, final DavServletResponse response) throws DavException
+ {
+ final ManagedRepositoryContent managedRepository = getManagedRepository(locator.getWorkspaceName());
+ final LogicalResource logicalResource = new LogicalResource(RepositoryPathUtil.getLogicalResource(locator.getResourcePath()));
+
+ DavResource resource = null;
+
+ if (managedRepository != null)
+ {
+ final boolean isGet = WebdavMethodUtil.isReadMethod( request.getMethod() );
+ final boolean isPut = WebdavMethodUtil.isWriteMethod( request.getMethod() );
+
+ if (isGet)
+ {
+ resource = doGet(managedRepository, request, locator, logicalResource);
+ }
+
+ if (isPut)
+ {
+ resource = doPut(managedRepository, request, locator, logicalResource);
+ }
+ }
+ else
+ {
+ throw new DavException(HttpServletResponse.SC_NOT_FOUND, "Repository does not exist");
+ }
+
+ if (resource != null)
+ {
+ setHeaders(locator, response);
+ return resource;
+ }
+
+ throw new DavException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Could not get resource for method " + request.getMethod());
+ }
+
+ public DavResource createResource(final DavResourceLocator locator, final DavSession davSession) throws DavException
+ {
+ final ManagedRepositoryContent managedRepository = getManagedRepository(locator.getWorkspaceName());
+ final String logicalResource = RepositoryPathUtil.getLogicalResource(locator.getResourcePath());
+ final File resourceFile = new File ( managedRepository.getRepoRoot(), logicalResource);
+
+ return new ArchivaDavResource(resourceFile.getAbsolutePath(), logicalResource, mimeTypes, locator, this, null);
+ }
+
+ private DavResource doGet(ManagedRepositoryContent managedRepository, DavServletRequest request, DavResourceLocator locator, LogicalResource logicalResource) throws DavException
+ {
+ File resourceFile = new File ( managedRepository.getRepoRoot(), logicalResource.getPath());
+ ArchivaDavResource resource = new ArchivaDavResource(resourceFile.getAbsolutePath(), logicalResource.getPath(), mimeTypes, locator, this, null);
+
+ if ( !resource.isCollection() )
+ {
+ // At this point the incoming request can either be in default or
+ // legacy layout format.
+ try
+ {
+ boolean fromProxy = fetchContentFromProxies(managedRepository, request, logicalResource );
+
+ // Perform an adjustment of the resource to the managed
+ // repository expected path.
+ String localResourcePath = repositoryRequest.toNativePath( logicalResource.getPath(), managedRepository );
+ resourceFile = new File( managedRepository.getRepoRoot(), localResourcePath );
+
+ boolean previouslyExisted = resourceFile.exists();
+
+ // Attempt to fetch the resource from any defined proxy.
+ if ( fromProxy )
+ {
+ processAuditEvents(request, locator.getWorkspaceName(), logicalResource.getPath(), previouslyExisted, resourceFile, " (proxied)");
+ }
+ resource = new ArchivaDavResource(resourceFile.getAbsolutePath(), logicalResource.getPath(), mimeTypes, locator, this, null);
+
+ }
+ catch ( LayoutException e )
+ {
+ throw new DavException(HttpServletResponse.SC_NOT_FOUND, e);
+ }
+ }
+ return resource;
+ }
+
+ private DavResource doPut(ManagedRepositoryContent managedRepository, DavServletRequest request, DavResourceLocator locator, LogicalResource logicalResource) throws DavException
+ {
+ /*
+ * Create parent directories that don't exist when writing a file
+ * This actually makes this implementation not compliant to the
+ * WebDAV RFC - but we have enough knowledge about how the
+ * collection is being used to do this reasonably and some versions
+ * of Maven's WebDAV don't correctly create the collections
+ * themselves.
+ */
+
+ File rootDirectory = new File(managedRepository.getRepoRoot());
+ File destDir = new File( rootDirectory, logicalResource.getPath() ).getParentFile();
+ if ( !destDir.exists() )
+ {
+ destDir.mkdirs();
+ String relPath =
+ PathUtil.getRelative( rootDirectory.getAbsolutePath(), destDir );
+ triggerAuditEvent(request, logicalResource.getPath(), relPath, AuditEvent.CREATE_DIR );
+ }
+
+ File resourceFile = new File( managedRepository.getRepoRoot(), logicalResource.getPath() );
+
+ boolean previouslyExisted = resourceFile.exists();
+
+ processAuditEvents(request, locator.getWorkspaceName(), logicalResource.getPath(), previouslyExisted, resourceFile, null );
+
+ return new ArchivaDavResource(resourceFile.getAbsolutePath(), logicalResource.getPath(), mimeTypes, locator, this, null);
+ }
+
+ private boolean fetchContentFromProxies( ManagedRepositoryContent managedRepository, DavServletRequest request, LogicalResource resource )
+ throws DavException
+ {
+ if ( repositoryRequest.isSupportFile( resource.getPath() ) )
+ {
+ // Checksums are fetched with artifact / metadata.
+
+ // Need to adjust the path for the checksum resource.
+ return false;
+ }
+
+ // Is it a Metadata resource?
+ if ( repositoryRequest.isDefault( resource.getPath() ) && repositoryRequest.isMetadata( resource.getPath() ) )
+ {
+ return fetchMetadataFromProxies(managedRepository, request, resource );
+ }
+
+ // Not any of the above? Then it's gotta be an artifact reference.
+ try
+ {
+ // Get the artifact reference in a layout neutral way.
+ ArtifactReference artifact = repositoryRequest.toArtifactReference( resource.getPath() );
+
+ if ( artifact != null )
+ {
+ applyServerSideRelocation(managedRepository, artifact );
+
+ File proxiedFile = connectors.fetchFromProxies( managedRepository, artifact );
+
+ resource.setPath( managedRepository.toPath( artifact ) );
+
+ return ( proxiedFile != null );
+ }
+ }
+ catch ( LayoutException e )
+ {
+ /* eat it */
+ }
+ catch ( ProxyDownloadException e )
+ {
+ log.error(e.getMessage(), e);
+ throw new DavException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Unable to fetch artifact resource.");
+ }
+ return false;
+ }
+
+ private boolean fetchMetadataFromProxies(ManagedRepositoryContent managedRepository, DavServletRequest request, LogicalResource resource )
+ throws DavException
+ {
+ ProjectReference project;
+ VersionedReference versioned;
+
+ try
+ {
+
+ versioned = metadataTools.toVersionedReference( resource.getPath() );
+ if ( versioned != null )
+ {
+ connectors.fetchFromProxies( managedRepository, versioned );
+ return true;
+ }
+ }
+ catch ( RepositoryMetadataException e )
+ {
+ log.error(e.getMessage(), e);
+ }
+
+ try
+ {
+ project = metadataTools.toProjectReference( resource.getPath() );
+ if ( project != null )
+ {
+ connectors.fetchFromProxies( managedRepository, project );
+ return true;
+ }
+ }
+ catch ( RepositoryMetadataException e )
+ {
+ log.error(e.getMessage(), e);
+ }
+
+ return false;
+ }
+
+ /**
+ * A relocation capable client will request the POM prior to the artifact,
+ * and will then read meta-data and do client side relocation. A simplier
+ * client (like maven 1) will only request the artifact and not use the
+ * metadatas.
+ *
+ * For such clients, archiva does server-side relocation by reading itself
+ * the <relocation> element in metadatas and serving the expected
+ * artifact.
+ */
+ protected void applyServerSideRelocation( ManagedRepositoryContent managedRepository, ArtifactReference artifact )
+ throws ProxyDownloadException
+ {
+ if ( "pom".equals( artifact.getType() ) )
+ {
+ return;
+ }
+
+ // Build the artifact POM reference
+ ArtifactReference pomReference = new ArtifactReference();
+ pomReference.setGroupId( artifact.getGroupId() );
+ pomReference.setArtifactId( artifact.getArtifactId() );
+ pomReference.setVersion( artifact.getVersion() );
+ pomReference.setType( "pom" );
+
+ // Get the artifact POM from proxied repositories if needed
+ connectors.fetchFromProxies( managedRepository, pomReference );
+
+ // Open and read the POM from the managed repo
+ File pom = managedRepository.toFile( pomReference );
+
+ if ( !pom.exists() )
+ {
+ return;
+ }
+
+ try
+ {
+ Model model = new MavenXpp3Reader().read( new FileReader( pom ) );
+ DistributionManagement dist = model.getDistributionManagement();
+ if ( dist != null )
+ {
+ Relocation relocation = dist.getRelocation();
+ if ( relocation != null )
+ {
+ // artifact is relocated : update the repositoryPath
+ if ( relocation.getGroupId() != null )
+ {
+ artifact.setGroupId( relocation.getGroupId() );
+ }
+ if ( relocation.getArtifactId() != null )
+ {
+ artifact.setArtifactId( relocation.getArtifactId() );
+ }
+ if ( relocation.getVersion() != null )
+ {
+ artifact.setVersion( relocation.getVersion() );
+ }
+ }
+ }
+ }
+ catch ( FileNotFoundException e )
+ {
+ // Artifact has no POM in repo : ignore
+ }
+ catch ( IOException e )
+ {
+ // Unable to read POM : ignore.
+ }
+ catch ( XmlPullParserException e )
+ {
+ // Invalid POM : ignore
+ }
+ }
+
+ private void processAuditEvents( DavServletRequest request, String repositoryId, String resource,
+ boolean previouslyExisted, File resourceFile, String suffix )
+ {
+ if ( suffix == null )
+ {
+ suffix = "";
+ }
+
+ // Process Create Audit Events.
+ if ( !previouslyExisted && resourceFile.exists() )
+ {
+ if ( resourceFile.isFile() )
+ {
+ triggerAuditEvent( request, repositoryId, resource, AuditEvent.CREATE_FILE + suffix );
+ }
+ else if ( resourceFile.isDirectory() )
+ {
+ triggerAuditEvent( request, repositoryId, resource, AuditEvent.CREATE_DIR + suffix );
+ }
+ }
+ // Process Remove Audit Events.
+ else if ( previouslyExisted && !resourceFile.exists() )
+ {
+ if ( resourceFile.isFile() )
+ {
+ triggerAuditEvent( request, repositoryId, resource, AuditEvent.REMOVE_FILE + suffix );
+ }
+ else if ( resourceFile.isDirectory() )
+ {
+ triggerAuditEvent( request, repositoryId, resource, AuditEvent.REMOVE_DIR + suffix );
+ }
+ }
+ // Process modify events.
+ else
+ {
+ if ( resourceFile.isFile() )
+ {
+ triggerAuditEvent( request, repositoryId, resource, AuditEvent.MODIFY_FILE + suffix );
+ }
+ }
+ }
+
+ private void triggerAuditEvent( String user, String remoteIP, String repositoryId, String resource, String action )
+ {
+ AuditEvent event = new AuditEvent( repositoryId, user, resource, action );
+ event.setRemoteIP( remoteIP );
+
+ for ( AuditListener listener : auditListeners )
+ {
+ listener.auditEvent( event );
+ }
+ }
+
+ private void triggerAuditEvent( DavServletRequest request, String repositoryId, String resource, String action )
+ {
+ triggerAuditEvent( ArchivaXworkUser.getActivePrincipal( ActionContext.getContext().getSession() ), getRemoteIP( request ), repositoryId, resource, action );
+ }
+
+ private String getRemoteIP( DavServletRequest request )
+ {
+ return request.getRemoteAddr();
+ }
+
+ public void addAuditListener( AuditListener listener )
+ {
+ this.auditListeners.add( listener );
+ }
+
+ public void clearAuditListeners()
+ {
+ this.auditListeners.clear();
+ }
+
+ public void removeAuditListener( AuditListener listener )
+ {
+ this.auditListeners.remove( listener );
+ }
+
+ private void setHeaders(DavResourceLocator locator, DavServletResponse response)
+ {
+ // [MRM-503] - Metadata file need Pragma:no-cache response
+ // header.
+ if ( locator.getResourcePath().endsWith( "/maven-metadata.xml" ) )
+ {
+ response.addHeader( "Pragma", "no-cache" );
+ response.addHeader( "Cache-Control", "no-cache" );
+ }
+
+ // TODO: [MRM-524] determine http caching options for other types of files (artifacts, sha1, md5, snapshots)
+ }
+
+ private ManagedRepositoryContent getManagedRepository(String respositoryId) throws DavException
+ {
+ if (respositoryId != null)
+ {
+ try
+ {
+ return repositoryFactory.getManagedRepositoryContent(respositoryId);
+ }
+ catch (RepositoryNotFoundException e)
+ {
+ throw new DavException(HttpServletResponse.SC_NOT_FOUND, e);
+ }
+ catch (RepositoryException e)
+ {
+ throw new DavException(HttpServletResponse.SC_NOT_FOUND, e);
+ }
+ }
+ return null;
+ }
+
+ class LogicalResource
+ {
+ private String path;
+
+ public LogicalResource(String path)
+ {
+ this.path = path;
+ }
+
+ public String getPath()
+ {
+ return path;
+ }
+
+ public void setPath(String path)
+ {
+ this.path = path;
+ }
+ }
+}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceLocator.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceLocator.java
new file mode 100644
index 000000000..0313ea80a
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceLocator.java
@@ -0,0 +1,136 @@
+package org.apache.maven.archiva.webdav;
+
+/*
+ * 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.
+ */
+
+import org.apache.jackrabbit.webdav.DavResourceLocator;
+import org.apache.jackrabbit.webdav.DavLocatorFactory;
+import org.apache.jackrabbit.util.Text;
+
+/**
+ * @author James William Dumay
+ */
+public class ArchivaDavResourceLocator implements DavResourceLocator
+{
+ private String prefix;
+
+ private String resourcePath;
+
+ private String href;
+
+ private String workspaceName;
+
+ private DavLocatorFactory davLocatorFactory;
+
+ public ArchivaDavResourceLocator(String prefix, String resourcePath, String workspaceName, DavLocatorFactory davLocatorFactory)
+ {
+ this.prefix = prefix;
+ this.workspaceName = workspaceName;
+ this.davLocatorFactory = davLocatorFactory;
+
+ // remove trailing '/' that is not part of the resourcePath except for the root item.
+ if (resourcePath.endsWith("/") && !"/".equals(resourcePath)) {
+ resourcePath = resourcePath.substring(0, resourcePath.length()-1);
+ }
+ this.resourcePath = resourcePath;
+
+ href = prefix + Text.escapePath(resourcePath);
+ }
+
+ public String getPrefix()
+ {
+ return prefix;
+ }
+
+ public String getResourcePath()
+ {
+ return resourcePath;
+ }
+
+ public String getWorkspacePath()
+ {
+ return "";
+ }
+
+ public String getWorkspaceName()
+ {
+ return workspaceName;
+ }
+
+ public boolean isSameWorkspace(DavResourceLocator locator)
+ {
+ return isSameWorkspace(locator.getWorkspaceName());
+ }
+
+ public boolean isSameWorkspace(String workspaceName)
+ {
+ return getWorkspaceName().equals(workspaceName);
+ }
+
+ public String getHref(boolean isCollection)
+ {
+ // avoid doubled trailing '/' for the root item
+ String suffix = (isCollection && !isRootLocation()) ? "/" : "";
+ return href + suffix;
+ }
+
+ public boolean isRootLocation()
+ {
+ return "/".equals(resourcePath);
+ }
+
+ public DavLocatorFactory getFactory()
+ {
+ return davLocatorFactory;
+ }
+
+ public String getRepositoryPath()
+ {
+ return getResourcePath();
+ }
+
+ /**
+ * Computes the hash code from the href, which is built using the final
+ * fields prefix and resourcePath.
+ *
+ * @return the hash code
+ */
+ public int hashCode()
+ {
+ return href.hashCode();
+ }
+
+ /**
+ * Equality of path is achieved if the specified object is a DavResourceLocator
+ * object with the same hash code.
+ *
+ * @param obj the object to compare to
+ * @return true
if the 2 objects are equal;
+ * false
otherwise
+ */
+ public boolean equals(Object obj)
+ {
+ if (obj instanceof DavResourceLocator)
+ {
+ DavResourceLocator other = (DavResourceLocator) obj;
+ return hashCode() == other.hashCode();
+ }
+ return false;
+ }
+}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSession.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSession.java
new file mode 100644
index 000000000..1fa20b042
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSession.java
@@ -0,0 +1,53 @@
+package org.apache.maven.archiva.webdav;
+
+/*
+ * 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.
+ */
+
+import org.apache.jackrabbit.webdav.DavSession;
+
+/**
+ * @author James William Dumay
+ */
+public class ArchivaDavSession implements DavSession
+{
+ public void addReference(Object o)
+ {
+ throw new UnsupportedOperationException("No yet implemented.");
+ }
+
+ public void removeReference(Object o)
+ {
+ throw new UnsupportedOperationException("No yet implemented.");
+ }
+
+ public void addLockToken(String s)
+ {
+ throw new UnsupportedOperationException("No yet implemented.");
+ }
+
+ public String[] getLockTokens()
+ {
+ throw new UnsupportedOperationException("No yet implemented.");
+ }
+
+ public void removeLockToken(String s)
+ {
+ throw new UnsupportedOperationException("No yet implemented.");
+ }
+}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java
new file mode 100644
index 000000000..766426105
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java
@@ -0,0 +1,154 @@
+package org.apache.maven.archiva.webdav;
+
+/*
+ * 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.
+ */
+
+import org.apache.jackrabbit.webdav.DavSessionProvider;
+import org.apache.jackrabbit.webdav.WebdavRequest;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.DavServletRequest;
+import org.apache.maven.archiva.webdav.util.WebdavMethodUtil;
+import org.apache.maven.archiva.webdav.util.RepositoryPathUtil;
+import org.apache.maven.archiva.security.ArchivaRoleConstants;
+import org.codehaus.plexus.redback.xwork.filter.authentication.HttpAuthenticator;
+import org.codehaus.plexus.redback.authentication.AuthenticationResult;
+import org.codehaus.plexus.redback.authentication.AuthenticationException;
+import org.codehaus.plexus.redback.system.SecuritySystem;
+import org.codehaus.plexus.redback.system.SecuritySession;
+import org.codehaus.plexus.redback.policy.MustChangePasswordException;
+import org.codehaus.plexus.redback.policy.AccountLockedException;
+import org.codehaus.plexus.redback.authorization.AuthorizationResult;
+import org.codehaus.plexus.redback.authorization.AuthorizationException;
+import org.codehaus.plexus.spring.PlexusToSpringUtils;
+import org.springframework.web.context.WebApplicationContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletException;
+import java.io.IOException;
+
+/**
+ * @author James William Dumay
+ */
+public class ArchivaDavSessionProvider implements DavSessionProvider
+{
+ private Logger log = LoggerFactory.getLogger(ArchivaDavSessionProvider.class);
+
+ private SecuritySystem securitySystem;
+
+ private HttpAuthenticator httpAuth;
+
+ public ArchivaDavSessionProvider(WebApplicationContext applicationContext)
+ {
+ securitySystem = (SecuritySystem) applicationContext.getBean( PlexusToSpringUtils.buildSpringId( SecuritySystem.ROLE ) );
+ httpAuth = (HttpAuthenticator) applicationContext.getBean( PlexusToSpringUtils.buildSpringId( HttpAuthenticator.ROLE, "basic" ) );
+ }
+
+ public boolean attachSession(WebdavRequest request) throws DavException
+ {
+ final String repositoryId = RepositoryPathUtil.getRepositoryName(removeContextPath(request));
+ return isAuthenticated(request, repositoryId) && isAuthorized(request, repositoryId);
+ }
+
+ public void releaseSession(WebdavRequest webdavRequest)
+ {
+ }
+
+ protected boolean isAuthenticated( WebdavRequest request, String repositoryId )
+ throws DavException
+ {
+ // Authentication Tests.
+ try
+ {
+ AuthenticationResult result = httpAuth.getAuthenticationResult(request, null);
+
+ if ( result == null || !result.isAuthenticated() )
+ {
+ //Unfortunatly, the DavSessionProvider does not pass in the response
+ httpAuth.authenticate(request, null);
+ }
+ }
+ catch ( AuthenticationException e )
+ {
+ throw new UnauthorizedDavException(repositoryId, "You are not authenticated");
+ }
+ catch ( AccountLockedException e )
+ {
+ throw new UnauthorizedDavException(repositoryId, "User account is locked.");
+ }
+ catch ( MustChangePasswordException e )
+ {
+ throw new UnauthorizedDavException(repositoryId, "You must change your password.");
+ }
+
+ return true;
+ }
+
+ protected boolean isAuthorized( WebdavRequest request, String repositoryId )
+ throws DavException
+ {
+ // Authorization Tests.
+ final boolean isWriteRequest = WebdavMethodUtil.isWriteMethod( request.getMethod() );
+
+ SecuritySession securitySession = httpAuth.getSecuritySession();
+ try
+ {
+ String permission = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS;
+
+ if ( isWriteRequest )
+ {
+ permission = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD;
+ }
+
+ //DavServletRequestInfo requestInfo = new DavServletRequestInfo(request);
+
+ AuthorizationResult authzResult =
+ securitySystem.authorize( securitySession, permission, repositoryId);
+
+ if ( !authzResult.isAuthorized() )
+ {
+ if ( authzResult.getException() != null )
+ {
+ log.info( "Authorization Denied [ip=" + request.getRemoteAddr() + ",isWriteRequest=" + isWriteRequest +
+ ",permission=" + permission + ",repo=" + repositoryId + "] : " +
+ authzResult.getException().getMessage() );
+ }
+ throw new DavException(HttpServletResponse.SC_UNAUTHORIZED, "Access denied for repository " + repositoryId);
+ }
+ }
+ catch ( AuthorizationException e )
+ {
+ log.error(e.getMessage(), e);
+ throw new DavException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Fatal Authorization Subsystem Error." );
+ }
+
+ return true;
+ }
+
+ private String removeContextPath(final DavServletRequest request)
+ {
+ String path = request.getRequestURI();
+ String ctx = request.getContextPath();
+ if (path.startsWith(ctx)) {
+ path = path.substring(ctx.length());
+ }
+ return path;
+ }
+}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DavServerComponent.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DavServerComponent.java
deleted file mode 100644
index db4389f46..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DavServerComponent.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.maven.archiva.webdav;
-
-import org.apache.maven.archiva.webdav.servlet.DavServerRequest;
-
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletResponse;
-import java.io.File;
-import java.io.IOException;
-
-/**
- * DavServerComponent
- *
- * @author Joakim Erdfelt
- * @version $Id: DavServerComponent.java 6000 2007-03-04 22:01:49Z joakime $
- */
-public interface DavServerComponent
-{
- /** The Plexus ROLE name */
- public static final String ROLE = DavServerComponent.class.getName();
-
- /**
- * Get the Prefix for this server component.
- * @return the prefix associated with this component.
- */
- public String getPrefix();
-
- /**
- * Set the prefix for this server component.
- * @param prefix the prefix to use.
- */
- public void setPrefix( String prefix );
-
- /**
- *
- * Flag to indicate how the dav server component should treat a GET request against
- * a DAV Collection.
- *
- *
- *
- * If true, the collection being requested will be searched for an index.html (or index.htm)
- * file to serve back, before it defaults to displaying the collection (directory) contents.
- *
- *
- *
- * If false, the collection will always be presented in as a list of contents.
- *
- *
- * @return true to use the index.html instead of directory contents.
- */
- public boolean isUseIndexHtml();
-
- /**
- *
- * Flag to indicate how the dav server component should treat a GET request against
- * a DAV Collection.
- *
- *
- *
- * If true, the collection being requested will be searched for an index.html (or index.htm)
- * file to serve back, before it defaults to displaying the collection (directory) contents.
- *
- *
- *
- * If false, the collection will always be presented in as a list of contents.
- *
- *
- * @param useIndexHtml true to use the index.html instead of directory contents.
- */
- public void setUseIndexHtml( boolean useIndexHtml );
-
- /**
- * Get the root directory for this server.
- *
- * @return the root directory for this server.
- */
- public File getRootDirectory();
-
- /**
- * Set the root directory for this server's content.
- *
- * @param rootDirectory the root directory for this server's content.
- */
- public void setRootDirectory( File rootDirectory );
-
- /**
- * Add a Server Listener for this server component.
- *
- * @param listener the listener to add for this component.
- */
- public void addListener( DavServerListener listener );
-
- /**
- * Remove a server listener for this server component.
- *
- * @param listener the listener to remove.
- */
- public void removeListener( DavServerListener listener );
-
- /**
- * Perform any initialization needed.
- *
- * @param servletConfig the servlet config that might be needed.
- * @throws DavServerException if there was a problem initializing the server component.
- */
- public void init( ServletConfig servletConfig ) throws DavServerException;
-
- /**
- * Performs a simple filesystem check for the specified resource.
- *
- * @param resource the resource to check for.
- * @return true if the resource exists.
- */
- public boolean hasResource( String resource );
-
- /**
- * Process incoming request.
- *
- * @param request the incoming request to process.
- * @param response the outgoing response to provide.
- */
- public void process( DavServerRequest request, HttpServletResponse response )
- throws DavServerException, ServletException, IOException;
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DavServerListener.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DavServerListener.java
deleted file mode 100644
index 251cee6ad..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DavServerListener.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.maven.archiva.webdav;
-
-/**
- * DavServerListener
- *
- * @author Joakim Erdfelt
- * @version $Id: DavServerListener.java 5379 2007-01-07 22:54:41Z joakime $
- */
-public interface DavServerListener
-{
- public void serverCollectionCreated( DavServerComponent server, String resource );
-
- public void serverCollectionRemoved( DavServerComponent server, String resource );
-
- public void serverResourceCreated( DavServerComponent server, String resource );
-
- public void serverResourceRemoved( DavServerComponent server, String resource );
-
- public void serverResourceModified( DavServerComponent server, String resource );
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DavServerManager.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DavServerManager.java
deleted file mode 100644
index 7c86cd533..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DavServerManager.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.maven.archiva.webdav;
-
-import java.io.File;
-import java.util.Collection;
-
-/**
- * DavServerManager
- *
- * @author Joakim Erdfelt
- * @version $Id: DavServerManager.java 6017 2007-03-06 00:39:53Z joakime $
- */
-public interface DavServerManager
-{
- /** The Plexus ROLE name. */
- public static final String ROLE = DavServerManager.class.getName();
-
- /**
- * Create a DavServerComponent and start tracking it.
- *
- * @param prefix the prefix for this component.
- * @param rootDirectory the root directory for this component's content. null to not set a root directory.
- * @return the created component, suitable for use.
- * @throws DavServerException
- */
- public DavServerComponent createServer( String prefix, File rootDirectory ) throws DavServerException;
-
- /**
- * Get the collection of tracked servers.
- *
- * @return Collection of {@link DavServerComponent} objects.
- */
- public Collection getServers();
-
- /**
- * Removes a specific server from the tracked list of servers.
- *
- * NOTE: This does not remove the associated files on disk, merely the reference being tracked.
- *
- * @param prefix the prefix to remove.
- */
- public void removeServer( String prefix );
-
- /**
- * Get the {@link DavServerComponent} associated with the specified prefix.
- *
- * @param prefix the prefix for the dav server component to use.
- * @return the DavServerComponent, or null if not found.
- */
- public DavServerComponent getServer( String prefix );
-
- /**
- * Remove all servers being tracked by the manager.
- */
- public void removeAllServers();
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DefaultDavServerManager.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DefaultDavServerManager.java
deleted file mode 100644
index b66edee3f..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DefaultDavServerManager.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.maven.archiva.webdav;
-
-import java.io.File;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * DefaultDavServerManager
- *
- * @author Joakim Erdfelt
- * @version $Id: DefaultDavServerManager.java 7009 2007-10-25 23:34:43Z joakime $
- *
- * @plexus.component role="org.apache.maven.archiva.webdav.DavServerManager" role-hint="default"
- */
-public class DefaultDavServerManager
- implements DavServerManager
-{
- /**
- * @plexus.requirement role-hint="simple"
- */
- private DavServerComponent server;
-
- private Map servers;
-
- public DefaultDavServerManager()
- {
- servers = new HashMap();
- }
-
- public DavServerComponent createServer( String prefix, File rootDirectory )
- throws DavServerException
- {
- if ( servers.containsKey( prefix ) )
- {
- throw new DavServerException( "Unable to create a new server on a pre-existing prefix [" + prefix + "]" );
- }
-
- server.setPrefix( prefix );
- if ( rootDirectory != null )
- {
- server.setRootDirectory( rootDirectory );
- }
-
- servers.put( prefix, server );
-
- return server;
- }
-
- public DavServerComponent getServer( String prefix )
- {
- return (DavServerComponent) servers.get( prefix );
- }
-
- public void removeServer( String prefix )
- {
- servers.remove( prefix );
- }
-
- public Collection getServers()
- {
- return servers.values();
- }
-
- public void removeAllServers()
- {
- servers.clear();
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/DavServerRequest.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/LogicalResource.java
similarity index 58%
rename from archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/DavServerRequest.java
rename to archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/LogicalResource.java
index 913e5a7f8..964fc2e6d 100644
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/DavServerRequest.java
+++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/LogicalResource.java
@@ -1,3 +1,5 @@
+package org.apache.maven.archiva.webdav;
+
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -7,7 +9,7 @@
* "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
+ * 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
@@ -17,23 +19,20 @@
* under the License.
*/
-package org.apache.maven.archiva.webdav.servlet;
-
-import org.apache.maven.archiva.webdav.util.WrappedRepositoryRequest;
-
/**
- * DavServerRequest
- *
- * @author Joakim Erdfelt
- * @version $Id: DavServerRequest.java 7073 2007-11-22 04:04:50Z brett $
+ * @author James William Dumay
*/
-public interface DavServerRequest
+public class LogicalResource
{
- public String getPrefix();
-
- public String getLogicalResource();
+ private String path;
- public void setLogicalResource( String logicalResource );
+ public String getPath()
+ {
+ return path;
+ }
- public WrappedRepositoryRequest getRequest();
+ public void setPath(String path)
+ {
+ this.path = path;
+ }
}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DavServerException.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/UnauthorizedDavException.java
similarity index 59%
rename from archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DavServerException.java
rename to archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/UnauthorizedDavException.java
index 893f059ef..d26f2f910 100644
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DavServerException.java
+++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/UnauthorizedDavException.java
@@ -1,3 +1,5 @@
+package org.apache.maven.archiva.webdav;
+
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -7,7 +9,7 @@
* "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
+ * 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
@@ -17,35 +19,25 @@
* under the License.
*/
-package org.apache.maven.archiva.webdav;
+import org.apache.jackrabbit.webdav.DavException;
+
+import javax.servlet.http.HttpServletResponse;
/**
- * DavServerException
- *
- * @author Joakim Erdfelt
- * @version $Id: DavServerException.java 5379 2007-01-07 22:54:41Z joakime $
+ * @author James William Dumay
*/
-public class DavServerException
- extends Exception
+public class UnauthorizedDavException extends DavException
{
+ final private String repositoryName;
- public DavServerException()
- {
- }
-
- public DavServerException( String message )
- {
- super( message );
- }
-
- public DavServerException( Throwable cause )
+ public UnauthorizedDavException(String repositoryName, String message)
{
- super( cause );
+ super(HttpServletResponse.SC_UNAUTHORIZED, message);
+ this.repositoryName = repositoryName;
}
- public DavServerException( String message, Throwable cause )
+ public String getRepositoryName()
{
- super( message, cause );
+ return repositoryName;
}
-
}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/AbstractWebDavServlet.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/AbstractWebDavServlet.java
deleted file mode 100644
index b654f359a..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/AbstractWebDavServlet.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.maven.archiva.webdav.servlet;
-
-import org.apache.commons.lang.BooleanUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.maven.archiva.webdav.DavServerManager;
-import org.codehaus.plexus.spring.PlexusToSpringUtils;
-import org.springframework.web.context.WebApplicationContext;
-import org.springframework.web.context.support.WebApplicationContextUtils;
-
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.Enumeration;
-
-/**
- * AbstractWebDavServlet
- *
- * @author Joakim Erdfelt
- * @version $Id: AbstractWebDavServlet.java 7009 2007-10-25 23:34:43Z joakime $
- */
-public abstract class AbstractWebDavServlet
- extends HttpServlet
-{
- public static final String INIT_USE_INDEX_HTML = "dav.use.index.html";
-
- private boolean debug = false;
-
- protected DavServerManager davManager;
-
- public String getServletInfo()
- {
- return "Plexus WebDAV Servlet";
- }
-
- public void init( ServletConfig config )
- throws ServletException
- {
- super.init( config );
-
- WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext( config.getServletContext() );
- davManager = (DavServerManager) wac.getBean( PlexusToSpringUtils.buildSpringId( DavServerManager.ROLE ) );
- if ( davManager == null )
- {
- throw new ServletException( "Unable to lookup davManager" );
- }
- }
-
- /**
- * Perform any authentication steps here.
- *
- * If authentication fails, it is the responsibility of the implementor to issue
- * the appropriate status codes and/or challenge back on the response object, then
- * return false on the overridden version of this method.
- *
- * To effectively not have authentication, just implement this method and always
- * return true.
- *
- * @param davRequest the incoming dav request.
- * @param httpResponse the outgoing http response.
- * @return true if user is authenticated, false if not.
- * @throws ServletException if there was a problem performing authencation.
- * @throws IOException if there was a problem obtaining credentials or issuing challenge.
- */
- public boolean isAuthenticated( DavServerRequest davRequest, HttpServletResponse httpResponse )
- throws ServletException, IOException
- {
- // Always return true. Effectively no Authentication done.
- return true;
- }
-
- /**
- * Perform any authorization steps here.
- *
- * If authorization fails, it is the responsibility of the implementor to issue
- * the appropriate status codes and/or challenge back on the response object, then
- * return false on the overridden version of this method.
- *
- * to effectively not have authorization, just implement this method and always
- * return true.
- *
- * @param davRequest
- * @param httpResponse
- * @return
- * @throws ServletException
- * @throws IOException
- */
- public boolean isAuthorized( DavServerRequest davRequest, HttpServletResponse httpResponse )
- throws ServletException, IOException
- {
- // Always return true. Effectively no Authorization done.
- return true;
- }
-
- public boolean isDebug()
- {
- return debug;
- }
-
- public void setDebug( boolean debug )
- {
- this.debug = debug;
- }
-
- protected void requestDebug( HttpServletRequest request )
- {
- if ( debug )
- {
- System.out.println( "-->>> request ----------------------------------------------------------" );
- System.out.println( "--> " + request.getScheme() + "://" + request.getServerName() + ":"
- + request.getServerPort() + request.getServletPath() );
- System.out.println( request.getMethod() + " " + request.getRequestURI()
- + ( request.getQueryString() != null ? "?" + request.getQueryString() : "" ) + " " + "HTTP/1.1" );
-
- Enumeration enHeaders = request.getHeaderNames();
- while ( enHeaders.hasMoreElements() )
- {
- String headerName = (String) enHeaders.nextElement();
- String headerValue = request.getHeader( headerName );
- System.out.println( headerName + ": " + headerValue );
- }
-
- System.out.println();
-
- System.out.println( "------------------------------------------------------------------------" );
- }
- }
-
- public abstract void setUseIndexHtml( boolean useIndexHtml );
-
- public boolean getUseIndexHtml( ServletConfig config )
- throws ServletException
- {
- String useIndexHtml = config.getInitParameter( INIT_USE_INDEX_HTML );
-
- if ( StringUtils.isEmpty( useIndexHtml ) )
- {
- return false;
- }
-
- return BooleanUtils.toBoolean( useIndexHtml );
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/basic/BasicDavServerRequest.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/basic/BasicDavServerRequest.java
deleted file mode 100644
index 3bbdc1703..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/basic/BasicDavServerRequest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.maven.archiva.webdav.servlet.basic;
-
-import org.apache.maven.archiva.webdav.servlet.DavServerRequest;
-import org.apache.maven.archiva.webdav.util.WrappedRepositoryRequest;
-
-/**
- * BasicDavServerRequest - for requests that have a prefix based off of the servlet path id.
- *
- * @author Joakim Erdfelt
- * @version $Id: BasicDavServerRequest.java 7073 2007-11-22 04:04:50Z brett $
- */
-public class BasicDavServerRequest
- implements DavServerRequest
-{
- private WrappedRepositoryRequest request;
-
- private String prefix;
-
- private String logicalResource;
-
- public BasicDavServerRequest( WrappedRepositoryRequest request )
- {
- this.request = request;
- this.prefix = request.getServletPath();
- this.logicalResource = request.getPathInfo();
- }
-
- public void setLogicalResource( String logicalResource )
- {
- this.logicalResource = logicalResource;
- this.request.setPathInfo( logicalResource );
- }
-
- public String getLogicalResource()
- {
- return this.logicalResource;
- }
-
- public String getPrefix()
- {
- return this.prefix;
- }
-
- public WrappedRepositoryRequest getRequest()
- {
- return request;
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/basic/BasicWebDavServlet.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/basic/BasicWebDavServlet.java
deleted file mode 100644
index 49193e31f..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/basic/BasicWebDavServlet.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.maven.archiva.webdav.servlet.basic;
-
-import org.apache.maven.archiva.webdav.DavServerComponent;
-import org.apache.maven.archiva.webdav.DavServerException;
-import org.apache.maven.archiva.webdav.servlet.AbstractWebDavServlet;
-import org.apache.maven.archiva.webdav.servlet.DavServerRequest;
-import org.apache.maven.archiva.webdav.util.WrappedRepositoryRequest;
-import org.codehaus.plexus.util.StringUtils;
-
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.File;
-import java.io.IOException;
-
-/**
- * BasicWebDavServlet - Basic implementation of a single WebDAV server as servlet.
- *
- * @author Joakim Erdfelt
- * @version $Id: BasicWebDavServlet.java 6017 2007-03-06 00:39:53Z joakime $
- */
-public class BasicWebDavServlet
- extends AbstractWebDavServlet
-{
- public static final String INIT_ROOT_DIRECTORY = "dav.root";
-
- private DavServerComponent davServer;
-
- // -----------------------------------------------------------------------
- // Servlet Implementation
- // -----------------------------------------------------------------------
-
- public void init( ServletConfig config )
- throws ServletException
- {
- super.init( config );
-
- String prefix = config.getServletName();
-
- boolean useIndexHtml = getUseIndexHtml( config );
- File rootDir = getRootDirectory( config );
-
- if ( rootDir != null && !rootDir.isDirectory() )
- {
- log( "Invalid configuration, the dav root " + rootDir.getPath()
- + " is not a directory: [" + rootDir.getAbsolutePath() + "]" );
- }
-
- try
- {
- davServer = davManager.createServer( prefix, rootDir );
- davServer.setUseIndexHtml( useIndexHtml );
- davServer.init( config );
- }
- catch ( DavServerException e )
- {
- throw new ServletException( "Unable to create DAV Server component for prefix [" + prefix
- + "] mapped to root directory [" + rootDir.getPath() + "]", e );
- }
- }
-
- public File getRootDirectory( ServletConfig config )
- throws ServletException
- {
- String rootDirName = config.getInitParameter( INIT_ROOT_DIRECTORY );
-
- if ( StringUtils.isEmpty( rootDirName ) )
- {
- log( "Init Parameter '" + INIT_ROOT_DIRECTORY + "' is empty." );
- return null;
- }
-
- return new File( rootDirName );
- }
-
- protected void service( HttpServletRequest httpRequest, HttpServletResponse httpResponse )
- throws ServletException, IOException
- {
- DavServerRequest davRequest = new BasicDavServerRequest( new WrappedRepositoryRequest( httpRequest ) );
-
- if ( davServer == null )
- {
- throw new ServletException( "Unable to service DAV request due to unconfigured DavServerComponent." );
- }
-
- requestDebug( httpRequest );
-
- if ( !isAuthenticated( davRequest, httpResponse ) )
- {
- return;
- }
-
- if ( !isAuthorized( davRequest, httpResponse ) )
- {
- return;
- }
-
- try
- {
- davServer.process( davRequest, httpResponse );
- }
- catch ( DavServerException e )
- {
- throw new ServletException( "Unable to process request.", e );
- }
- }
-
- public void setUseIndexHtml( boolean useIndexHtml )
- {
- davServer.setUseIndexHtml( useIndexHtml );
- }
-
- public DavServerComponent getDavServer()
- {
- return davServer;
- }
-
- public void setDavServer( DavServerComponent davServer )
- {
- this.davServer = davServer;
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/multiplexed/MultiplexedDavServerRequest.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/multiplexed/MultiplexedDavServerRequest.java
deleted file mode 100644
index b46a76d7a..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/multiplexed/MultiplexedDavServerRequest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.maven.archiva.webdav.servlet.multiplexed;
-
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.maven.archiva.webdav.servlet.DavServerRequest;
-import org.apache.maven.archiva.webdav.util.WrappedRepositoryRequest;
-
-/**
- *
- * MultiplexedDavServerRequest - For requests that contain the server prefix information within the requested
- * servlet's pathInfo parameter (as the first path entry).
- *
- *
- *
- * You would use this dav server request object when you are working with a single servlet that is handling
- * multiple dav server components.
- *
- *
- * @author Joakim Erdfelt
- * @version $Id: MultiplexedDavServerRequest.java 7073 2007-11-22 04:04:50Z brett $
- */
-public class MultiplexedDavServerRequest
- implements DavServerRequest
-{
- private WrappedRepositoryRequest request;
-
- private String prefix;
-
- private String logicalResource;
-
- public MultiplexedDavServerRequest( WrappedRepositoryRequest request )
- {
- String requestPathInfo = StringUtils.defaultString( request.getPathInfo() );
-
- // Remove prefixing slash as the repository id doesn't contain it;
- if ( requestPathInfo.startsWith( "/" ) )
- {
- requestPathInfo = requestPathInfo.substring( 1 );
- }
-
- // Find first element, if slash exists.
- int slash = requestPathInfo.indexOf( '/' );
- if ( slash > 0 )
- {
- // Filtered: "central/org/apache/maven/" -> "central"
- this.prefix = requestPathInfo.substring( 0, slash );
-
- this.logicalResource = requestPathInfo.substring( slash );
-
- if ( this.logicalResource.endsWith( "/.." ) )
- {
- this.logicalResource += "/";
- }
-
- /* Perform a simple security normalization of the requested pathinfo.
- * This is to prevent requests for information outside of the root directory.
- */
- this.logicalResource = FilenameUtils.normalize( logicalResource );
-
- if ( logicalResource != null )
- {
- logicalResource = logicalResource.replace( '\\', '/' );
-
- if ( logicalResource.startsWith( "//" ) )
- {
- logicalResource = logicalResource.substring( 1 );
- }
- }
- else
- {
- this.logicalResource = "/";
- }
- }
- else
- {
- this.prefix = requestPathInfo;
- this.logicalResource = "/";
- }
-
- this.request = request;
- this.request.setPathInfo( logicalResource );
- }
-
- public void setLogicalResource( String logicalResource )
- {
- this.logicalResource = logicalResource;
- this.request.setPathInfo( logicalResource );
- }
-
- public String getLogicalResource()
- {
- return this.logicalResource;
- }
-
- public String getPrefix()
- {
- return this.prefix;
- }
-
- public WrappedRepositoryRequest getRequest()
- {
- return request;
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/multiplexed/MultiplexedWebDavServlet.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/multiplexed/MultiplexedWebDavServlet.java
deleted file mode 100644
index 19d03093b..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/multiplexed/MultiplexedWebDavServlet.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.maven.archiva.webdav.servlet.multiplexed;
-
-import org.apache.maven.archiva.webdav.DavServerComponent;
-import org.apache.maven.archiva.webdav.DavServerException;
-import org.apache.maven.archiva.webdav.DavServerManager;
-import org.apache.maven.archiva.webdav.servlet.AbstractWebDavServlet;
-import org.apache.maven.archiva.webdav.servlet.DavServerRequest;
-import org.apache.maven.archiva.webdav.util.WrappedRepositoryRequest;
-
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.File;
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.util.Iterator;
-
-/**
- *
- * MultiplexedWebDavServlet - and abstracted multiplexed webdav servlet.
- *
- *
- *
- * Implementations of this servlet should override the {@link #initServers} method and create all of the
- * appropriate DavServerComponents needed using the {@link DavServerManager} obtained via the {@link #getDavManager()}
- * method.
- *
- *
- * @author Joakim Erdfelt
- * @version $Id: MultiplexedWebDavServlet.java 6000 2007-03-04 22:01:49Z joakime $
- */
-public abstract class MultiplexedWebDavServlet
- extends AbstractWebDavServlet
-{
- private boolean useIndexHtml = false;
-
- public void init( ServletConfig config )
- throws ServletException
- {
- super.init( config );
-
- this.useIndexHtml = getUseIndexHtml( config );
-
- try
- {
- initServers( config );
- }
- catch ( DavServerException e )
- {
- throw new ServletException( e );
- }
- }
-
- /**
- * Create any DavServerComponents here.
- * Use the {@link #createServer(String, File, ServletConfig)} method to create your servers.
- *
- * @param config the config to use.
- * @throws DavServerException if there was a problem initializing the server components.
- */
- public abstract void initServers( ServletConfig config )
- throws DavServerException;
-
- public DavServerComponent createServer( String prefix, File rootDirectory, ServletConfig config )
- throws DavServerException
- {
- DavServerComponent serverComponent = davManager.createServer( prefix, rootDirectory );
- serverComponent.setUseIndexHtml( useIndexHtml );
- serverComponent.init( config );
- return serverComponent;
- }
-
- protected void service( HttpServletRequest httpRequest, HttpServletResponse httpResponse )
- throws ServletException, IOException
- {
- DavServerRequest davRequest = new MultiplexedDavServerRequest( new WrappedRepositoryRequest( httpRequest ) );
-
- DavServerComponent davServer = davManager.getServer( davRequest.getPrefix() );
-
- if ( davServer == null )
- {
- String errorMessage = "[" + davRequest.getPrefix() + "] Not Found (Likely Unconfigured).";
- httpResponse.sendError( HttpURLConnection.HTTP_NOT_FOUND, errorMessage );
- return;
- }
-
- requestDebug( httpRequest );
-
- if ( !isAuthenticated( davRequest, httpResponse ) )
- {
- return;
- }
-
- if ( !isAuthorized( davRequest, httpResponse ) )
- {
- return;
- }
-
- try
- {
- davServer.process( davRequest, httpResponse );
- }
- catch ( DavServerException e )
- {
- throw new ServletException( "Unable to process request.", e );
- }
- }
-
- public void setUseIndexHtml( boolean useIndexHtml )
- {
- for ( Iterator it = davManager.getServers().iterator(); it.hasNext(); )
- {
- DavServerComponent davServer = (DavServerComponent) it.next();
- davServer.setUseIndexHtml( useIndexHtml );
- }
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/simple/HackedMoveMethod.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/simple/HackedMoveMethod.java
deleted file mode 100644
index 736a3c07e..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/simple/HackedMoveMethod.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.maven.archiva.webdav.simple;
-
-import it.could.webdav.DAVException;
-import it.could.webdav.DAVMethod;
-import it.could.webdav.DAVMultiStatus;
-import it.could.webdav.DAVResource;
-import it.could.webdav.DAVTransaction;
-
-import java.io.IOException;
-import java.net.URI;
-
-/**
- * HackedMoveMethod - Created to address the needs for inter-repository moves.
- *
- * @author Pier Fumagalli (Original it.could.webdav 0.4 version)
- * @author Joakim Erdfelt (Hacked Version)
- * @version $Id: HackedMoveMethod.java 6000 2007-03-04 22:01:49Z joakime $
- */
-public class HackedMoveMethod
- implements DAVMethod
-{
-
- public HackedMoveMethod()
- {
- super();
- }
-
- /**
- * Process the MOVE
method.
- */
- public void process( DAVTransaction transaction, DAVResource resource )
- throws IOException
- {
- URI target = transaction.getDestination();
- if ( target == null )
- throw new DAVException( 412, "No destination" );
-
- if ( target.getScheme() == null )
- {
- // This is a relative file system destination target.
- DAVResource dest = resource.getRepository().getResource( target );
- moveWithinRepository( transaction, resource, dest );
- }
- else
- {
- // This is a inter-repository move request.
- URI dest = target;
- moveInterRepository( transaction, resource, dest );
- }
- }
-
- private void moveInterRepository( DAVTransaction transaction, DAVResource resource, URI dest )
- throws DAVException
- {
- /* TODO: Figure out how to handle a Repository to Repository MOVE of content, and still maintain
- * the security credentials from the original request. (Need to support NTLM, Digest, BASIC)
- *
- * IDEA: Could support non-secured Webdav Destination using slide client libraries.
- */
- transaction.setStatus( 501 );
- throw new DAVException( 501, "Server side MOVE to external WebDAV instance not supported." );
- }
-
- private void moveWithinRepository( DAVTransaction transaction, DAVResource resource, DAVResource dest )
- throws IOException
- {
- int depth = transaction.getDepth();
- boolean recursive = false;
- if ( depth == 0 )
- {
- recursive = false;
- }
- else if ( depth == DAVTransaction.INFINITY )
- {
- recursive = true;
- }
- else
- {
- throw new DAVException( 412, "Invalid Depth specified" );
- }
-
- try
- {
- int status;
- if ( !dest.isNull() && !transaction.getOverwrite() )
- {
- status = 412; // MOVE-on-existing should fail with 412
- }
- else
- {
- resource.copy( dest, transaction.getOverwrite(), recursive );
- resource.delete();
-
- if ( transaction.getOverwrite() )
- {
- status = 204; // No Content
- }
- else
- {
- status = 201; // Created
- }
- }
- transaction.setStatus( status );
- }
- catch ( DAVMultiStatus multistatus )
- {
- multistatus.write( transaction );
- }
- }
-
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/simple/ReplacementGetMethod.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/simple/ReplacementGetMethod.java
deleted file mode 100644
index 3eee8786b..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/simple/ReplacementGetMethod.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.maven.archiva.webdav.simple;
-
-import it.could.util.StreamTools;
-import it.could.webdav.DAVException;
-import it.could.webdav.DAVInputStream;
-import it.could.webdav.DAVMethod;
-import it.could.webdav.DAVNotModified;
-import it.could.webdav.DAVResource;
-import it.could.webdav.DAVTransaction;
-import it.could.webdav.DAVUtilities;
-import org.apache.commons.lang.StringUtils;
-import org.apache.maven.archiva.webdav.util.MimeTypes;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.TreeSet;
-
-/**
- * ReplacementGetMethod
- *
- * @author Pier Fumagalli (Original it.could.webdav 0.4 version)
- * @author Joakim Erdfelt (Replacement Version)
- * @version $Id: ReplacementGetMethod.java 7002 2007-10-23 22:40:37Z joakime $
- *
- * @plexus.component
- * role="it.could.webdav.DAVMethod"
- * role-hint="get-with-indexing"
- */
-public class ReplacementGetMethod implements DAVMethod
-{
- /** The encoding charset to repsesent collections.
*/
- public static final String ENCODING = "UTF-8";
-
- /** The mime type that {@link ReplacementGetMethod} will use serving index.html files.
*/
- public static final String HTML_MIME_TYPE = "text/html";
-
- /** The mime type that {@link ReplacementGetMethod} will use serving collections.
*/
- public static final String COLLECTION_MIME_TYPE = HTML_MIME_TYPE + "; charset=\"" + ENCODING + "\"";
-
- /** The header for content disposition.
*/
- public static final String CONTENT_DISPOSITION = "Content-Disposition";
-
- /** The content-disposition for fancy-indexing.
*/
- public static final String INLINE_INDEX_HTML = "inline; filename=\"index.html\"";
-
- /**
- * @plexus.requirement
- */
- private MimeTypes mimeTypes;
-
- private boolean useIndexHtml = false;
-
- /**
- * Create a new {@link ReplacementGetMethod} instance.
- */
- public ReplacementGetMethod()
- {
- super();
- }
-
- /**
- * Process the GET
method.
- */
- public void process( DAVTransaction transaction, DAVResource resource ) throws IOException
- {
- // Handle boilerplate
- if ( resource.isNull() )
- throw new DAVException( 404, "Not found", resource );
-
- notModified( transaction, resource );
-
- copyHeaders( transaction, resource );
-
- // Process the request.
- final String originalPath = transaction.getOriginalPath();
- final String normalizedPath = transaction.getNormalizedPath();
- final String current;
- final String parent;
-
- if ( originalPath.equals( normalizedPath ) )
- {
- final String relativePath = resource.getRelativePath();
- if ( relativePath.equals( "" ) )
- {
- current = transaction.lookup( resource ).toASCIIString();
- }
- else
- {
- current = relativePath;
- }
- parent = "./";
- }
- else
- {
- current = "./";
- parent = "../";
- }
-
- if ( resource.isCollection() )
- {
- DAVResource indexHtml = null;
-
- if ( useIndexHtml )
- {
- for ( Iterator it = resource.getChildren(); it.hasNext(); )
- {
- DAVResource child = (DAVResource) it.next();
- String name = child.getDisplayName().toLowerCase();
- if ( StringUtils.equals( "index.html", name ) || StringUtils.equals( "index.htm", name ) )
- {
- indexHtml = child;
- break;
- }
- }
- }
-
- if ( useIndexHtml && indexHtml != null )
- {
- transaction.setContentType( COLLECTION_MIME_TYPE );
- transaction.setHeader( CONTENT_DISPOSITION, INLINE_INDEX_HTML );
- sendResource( transaction, indexHtml );
- }
- else
- {
- transaction.setContentType( COLLECTION_MIME_TYPE );
- transaction.setHeader( CONTENT_DISPOSITION, INLINE_INDEX_HTML );
- sendFancyIndex( transaction, resource, current, parent );
- }
- }
- else
- {
- /* Processing a normal resource request */
- transaction.setContentType( mimeTypes.getMimeType( resource.getDisplayName() ) );
- transaction.setHeader( CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getDisplayName() + "\"" );
- sendResource( transaction, resource );
- }
- }
-
- private void copyHeaders( DAVTransaction transaction, DAVResource resource )
- {
- /* Get the headers of this method */
- String ctyp = resource.getContentType();
- String etag = resource.getEntityTag();
- String lmod = DAVUtilities.formatHttpDate( resource.getLastModified() );
- String clen = DAVUtilities.formatNumber( resource.getContentLength() );
-
- /* Set the normal headers that are required for a GET */
- if ( ctyp != null )
- {
- transaction.setContentType( ctyp );
- }
-
- if ( etag != null )
- {
- transaction.setHeader( "ETag", etag );
- }
-
- if ( lmod != null )
- {
- transaction.setHeader( "Last-Modified", lmod );
- }
-
- if ( clen != null )
- {
- transaction.setHeader( "Content-Length", clen );
- }
- }
-
- private void sendResource( DAVTransaction transaction, DAVResource resource ) throws IOException
- {
- OutputStream out = null;
- DAVInputStream in = null;
-
- try
- {
- out = transaction.write();
- in = resource.read();
-
- byte buffer[] = new byte[4096 * 16];
- int k = -1;
- while ( ( k = in.read( buffer ) ) != -1 )
- {
- out.write( buffer, 0, k );
- }
-
- out.flush();
- }
- finally
- {
- StreamTools.close( in );
- StreamTools.close( out );
- }
- }
-
- private void sendFancyIndex( DAVTransaction transaction, DAVResource resource, final String current,
- final String parent ) throws IOException
- {
- PrintWriter out = transaction.write( ENCODING );
- String path = resource.getRelativePath();
- out.println( "" );
- out.println( "" );
- out.println( "Collection: /" + path + "" );
- out.println( "" );
- out.println( "" );
- out.println( "Collection: /" + path + "
" );
- out.println( "" );
- out.println( "" );
- }
-
- /* Process the children (in two sorted sets, for nice ordering) */
- Set resources = new TreeSet();
- Set collections = new TreeSet();
- Iterator iterator = resource.getChildren();
- while ( iterator.hasNext() )
- {
- final DAVResource child = (DAVResource) iterator.next();
- final StringBuffer buffer = new StringBuffer();
- final String childPath = child.getDisplayName();
- buffer.append( "- " );
- buffer.append( childPath );
- buffer.append( "
" );
- if ( child.isCollection() )
- {
- collections.add( buffer.toString() );
- }
- else
- {
- resources.add( buffer.toString() );
- }
- }
-
- /* Spit out the collections first and the resources then */
- for ( Iterator i = collections.iterator(); i.hasNext(); )
- out.println( i.next() );
- for ( Iterator i = resources.iterator(); i.hasNext(); )
- out.println( i.next() );
-
- out.println( "
" );
- out.println( "" );
- out.println( "" );
- out.flush();
- }
-
- private void notModified( DAVTransaction transaction, DAVResource resource )
- {
- Date ifmod = transaction.getIfModifiedSince();
- Date lsmod = resource.getLastModified();
- if ( resource.isResource() && ( ifmod != null ) && ( lsmod != null ) )
- {
- /* HTTP doesn't send milliseconds, but Java does, so, reset them */
- lsmod = new Date( ( (long) ( lsmod.getTime() / 1000 ) ) * 1000 );
- if ( !ifmod.before( lsmod ) )
- throw new DAVNotModified( resource );
- }
- }
-
- public boolean isUseIndexHtml()
- {
- return useIndexHtml;
- }
-
- public void setUseIndexHtml( boolean useIndexHtml )
- {
- this.useIndexHtml = useIndexHtml;
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/simple/SimpleDavServerComponent.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/simple/SimpleDavServerComponent.java
deleted file mode 100644
index af6794faf..000000000
--- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/simple/SimpleDavServerComponent.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.maven.archiva.webdav.simple;
-
-import it.could.webdav.DAVListener;
-import it.could.webdav.DAVProcessor;
-import it.could.webdav.DAVRepository;
-import it.could.webdav.DAVResource;
-import it.could.webdav.DAVTransaction;
-import org.apache.commons.lang.StringUtils;
-import org.apache.maven.archiva.webdav.AbstractDavServerComponent;
-import org.apache.maven.archiva.webdav.DavServerException;
-import org.apache.maven.archiva.webdav.servlet.DavServerRequest;
-
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletResponse;
-import java.io.File;
-import java.io.IOException;
-
-/**
- * SimpleDavServerComponent
- *
- * @author Joakim Erdfelt
- * @version $Id: SimpleDavServerComponent.java 7097 2007-11-30 12:57:29Z handyande $
- *
- * @plexus.component role="org.apache.maven.archiva.webdav.DavServerComponent"
- * role-hint="simple"
- * instantiation-strategy="per-lookup"
- */
-public class SimpleDavServerComponent
- extends AbstractDavServerComponent
- implements DAVListener
-{
- /**
- * @plexus.requirement
- * role="it.could.webdav.DAVMethod"
- * role-hint="get-with-indexing"
- */
- public ReplacementGetMethod methodGet;
-
- private String prefix;
-
- private File rootDirectory;
-
- private DAVRepository davRepository;
-
- private DAVProcessor davProcessor;
-
- public String getPrefix()
- {
- return prefix;
- }
-
- public File getRootDirectory()
- {
- return rootDirectory;
- }
-
- public void setPrefix( String prefix )
- {
- this.prefix = prefix;
- }
-
- public void setRootDirectory( File rootDirectory )
- {
- this.rootDirectory = rootDirectory;
- }
-
- public void init( ServletConfig servletConfig )
- throws DavServerException
- {
- servletConfig.getServletContext().log( "Initializing " + this.getClass().getName() );
- try
- {
- davRepository = new DAVRepository( rootDirectory );
- davProcessor = new DAVProcessor( davRepository );
- davRepository.addListener( this );
-
- hackDavProcessor( davProcessor );
- }
- catch ( IOException e )
- {
- throw new DavServerException( "Unable to initialize DAVRepository.", e );
- }
- }
-
- /**
- * Replace the problematic dav methods with local hacked versions.
- *
- * @param davProcessor
- * @throws DavServerException
- */
- private void hackDavProcessor( DAVProcessor davProcessor )
- throws DavServerException
- {
- davProcessor.setMethod( "MOVE", new HackedMoveMethod() );
- davProcessor.setMethod( "GET", methodGet );
-
- /* Reflection based technique.
- try
- {
- Field fldInstance = davProcessor.getClass().getDeclaredField( "INSTANCES" );
- fldInstance.setAccessible( true );
-
- Map mapInstances = (Map) fldInstance.get( davProcessor );
-
- // Replace MOVE method.
- // TODO: Remove MOVE method when upgrading it.could.webdav to v0.5
- mapInstances.put( "MOVE", (DAVMethod) new HackedMoveMethod() );
-
- // Replace GET method.
- mapInstances.put( "GET", (DAVMethod) methodGet );
- }
- catch ( Throwable e )
- {
- throw new DavServerException( "Unable to twiddle DAVProcessor.INSTANCES field.", e );
- }
- */
- }
-
- public void process( DavServerRequest request, HttpServletResponse response )
- throws ServletException, IOException
- {
- DAVTransaction transaction = new DAVTransaction( request.getRequest(), response );
-
- /* BEGIN - it.could.webdav hacks
- * TODO: Remove hacks with release of it.could.webdav 0.5 (or newer)
- */
- String depthValue = request.getRequest().getHeader( "Depth" );
- if ( StringUtils.equalsIgnoreCase( "infinity", depthValue ) )
- {
- // See - http://could.it/bugs/browse/DAV-3
- request.getRequest().setHeader( "Depth", "infinity" );
- }
- /* END - it.could.webdav hacks */
-
- davProcessor.process( transaction );
- }
-
- public void notify( DAVResource resource, int event )
- {
- switch ( event )
- {
- case DAVListener.COLLECTION_CREATED:
- triggerCollectionCreated( resource.getRelativePath() );
- break;
- case DAVListener.COLLECTION_REMOVED:
- triggerCollectionRemoved( resource.getRelativePath() );
- break;
- case DAVListener.RESOURCE_CREATED:
- triggerResourceCreated( resource.getRelativePath() );
- break;
- case DAVListener.RESOURCE_REMOVED:
- triggerResourceRemoved( resource.getRelativePath() );
- break;
- case DAVListener.RESOURCE_MODIFIED:
- triggerResourceModified( resource.getRelativePath() );
- break;
- }
- }
-
- public void setUseIndexHtml( boolean useIndexHtml )
- {
- super.setUseIndexHtml( useIndexHtml );
- this.methodGet.setUseIndexHtml( useIndexHtml );
- }
-}
diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/IndexWriter.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/IndexWriter.java
new file mode 100644
index 000000000..5c7beb917
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/IndexWriter.java
@@ -0,0 +1,111 @@
+package org.apache.maven.archiva.webdav.util;
+
+/*
+ * 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.
+ */
+
+import org.apache.jackrabbit.webdav.DavResource;
+import org.apache.jackrabbit.webdav.io.OutputContext;
+
+import java.util.Date;
+import java.io.PrintWriter;
+import java.io.File;
+
+/**
+ * @author James William Dumay
+ */
+public class IndexWriter
+{
+ private final DavResource resource;
+
+ private final File localResource;
+
+ private final String logicalResource;
+
+ public IndexWriter(DavResource resource, File localResource, String logicalResource)
+ {
+ this.resource = resource;
+ this.localResource = localResource;
+ this.logicalResource = logicalResource;
+ }
+
+ public void write(OutputContext outputContext)
+ {
+ outputContext.setModificationTime(new Date().getTime());
+ outputContext.setContentType("text/html");
+ outputContext.setETag("");
+ if (outputContext.hasStream())
+ {
+ PrintWriter writer = new PrintWriter(outputContext.getOutputStream());
+ writeDocumentStart(writer);
+ writeHyperlinks(writer);
+ writeDocumentEnd(writer);
+ writer.flush();
+ writer.close();
+ }
+ }
+
+ private void writeDocumentStart(PrintWriter writer)
+ {
+ writer.println("");
+ writer.println("");
+ writer.println("Collection: " + logicalResource + "");
+ writer.println("");
+ writer.println("Collection: " + logicalResource + "
");
+
+ //Check if not root
+ if (!"/".equals(logicalResource))
+ {
+ File file = new File(logicalResource);
+ String parentName = file.getParent().equals("") ? "/" : file.getParent();
+
+ writer.println("");
+ }
+
+ writer.println("");
+ }
+
+ private void writeDocumentEnd(PrintWriter writer)
+ {
+ writer.println("
");
+ writer.println("");
+ writer.println("