From: Brett Porter Date: Fri, 18 Apr 2008 03:05:18 +0000 (+0000) Subject: [MRM-781] Removal of Archiva-Webdav implementation in favor of Jackrabbit-webdav X-Git-Tag: archiva-r676265~182 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=558d0c2a4f609d4e2b414addf468d0574006f3d4;p=archiva.git [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 --- 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-security/src/main/java/org/apache/maven/archiva/security/ArchivaXworkUser.java b/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaXworkUser.java new file mode 100644 index 000000000..4189392e6 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaXworkUser.java @@ -0,0 +1,66 @@ +package org.apache.maven.archiva.security; + +/* + * 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.util.HashMap; +import java.util.Map; + +import org.apache.maven.archiva.security.ArchivaRoleConstants; +import org.codehaus.plexus.redback.system.SecuritySession; +import org.codehaus.plexus.redback.system.SecuritySystemConstants; +import org.codehaus.plexus.redback.users.User; + +/** + * ArchivaXworkUser + * + * @author Joakim Erdfelt + * @version $Id$ + */ +public class ArchivaXworkUser +{ + public static String getActivePrincipal( Map sessionMap ) + { + if ( sessionMap == null ) + { + return ArchivaRoleConstants.PRINCIPAL_GUEST; + } + + SecuritySession securitySession = + (SecuritySession) sessionMap.get( SecuritySystemConstants.SECURITY_SESSION_KEY ); + + if ( securitySession == null ) + { + securitySession = (SecuritySession) sessionMap.get( SecuritySession.ROLE ); + } + + if ( securitySession == null ) + { + return ArchivaRoleConstants.PRINCIPAL_GUEST; + } + + User user = securitySession.getUser(); + if ( user == null ) + { + return ArchivaRoleConstants.PRINCIPAL_GUEST; + } + + return (String) user.getPrincipal(); + } +} 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/java/org/apache/maven/archiva/web/util/ArchivaXworkUser.java b/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/util/ArchivaXworkUser.java deleted file mode 100644 index 208d82ebe..000000000 --- a/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/util/ArchivaXworkUser.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.apache.maven.archiva.web.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 java.util.HashMap; -import java.util.Map; - -import org.apache.maven.archiva.security.ArchivaRoleConstants; -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 - * - * @author Joakim Erdfelt - * @version $Id$ - */ -public class ArchivaXworkUser -{ - private static Map getContextSession() - { - ActionContext context = ActionContext.getContext(); - Map sessionMap = context.getSession(); - if ( sessionMap == null ) - { - sessionMap = new HashMap(); - } - - return sessionMap; - } - - private static SecuritySession getSecuritySession() - { - SecuritySession securitySession = - (SecuritySession) getContextSession().get( SecuritySystemConstants.SECURITY_SESSION_KEY ); - - if ( securitySession == null ) - { - securitySession = (SecuritySession) getContextSession().get( SecuritySession.ROLE ); - } - - return securitySession; - } - - public static String getActivePrincipal() - { - SecuritySession securitySession = getSecuritySession(); - - if ( securitySession == null ) - { - return ArchivaRoleConstants.PRINCIPAL_GUEST; - } - - User user = securitySession.getUser(); - if ( user == null ) - { - return ArchivaRoleConstants.PRINCIPAL_GUEST; - } - - return (String) user.getPrincipal(); - } -} 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:

- * - *
- * - * URL components - * - *
- * - *

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: -

-
- - URL components - -
- - \ 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(""); - 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/DavServerException.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DavServerException.java deleted file mode 100644 index 893f059ef..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/DavServerException.java +++ /dev/null @@ -1,51 +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; - -/** - * DavServerException - * - * @author Joakim Erdfelt - * @version $Id: DavServerException.java 5379 2007-01-07 22:54:41Z joakime $ - */ -public class DavServerException - extends Exception -{ - - public DavServerException() - { - } - - public DavServerException( String message ) - { - super( message ); - } - - public DavServerException( Throwable cause ) - { - super( cause ); - } - - public DavServerException( String message, Throwable cause ) - { - super( message, cause ); - } - -} 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/LogicalResource.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/LogicalResource.java new file mode 100644 index 000000000..964fc2e6d --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/LogicalResource.java @@ -0,0 +1,38 @@ +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. + */ + +/** + * @author James William Dumay + */ +public class LogicalResource +{ + private String 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/UnauthorizedDavException.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/UnauthorizedDavException.java new file mode 100644 index 000000000..d26f2f910 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/UnauthorizedDavException.java @@ -0,0 +1,43 @@ +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.DavException; + +import javax.servlet.http.HttpServletResponse; + +/** + * @author James William Dumay + */ +public class UnauthorizedDavException extends DavException +{ + final private String repositoryName; + + public UnauthorizedDavException(String repositoryName, String message) + { + super(HttpServletResponse.SC_UNAUTHORIZED, message); + this.repositoryName = repositoryName; + } + + public String getRepositoryName() + { + 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/DavServerRequest.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/DavServerRequest.java deleted file mode 100644 index 913e5a7f8..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/servlet/DavServerRequest.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.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 $ - */ -public interface DavServerRequest -{ - public String getPrefix(); - - public String getLogicalResource(); - - public void setLogicalResource( String logicalResource ); - - public WrappedRepositoryRequest getRequest(); -} 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( "" ); - 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 + "<title>"); + writer.println("</head>"); + writer.println("<h3>Collection: " + logicalResource + "</h3>"); + + //Check if not root + if (!"/".equals(logicalResource)) + { + File file = new File(logicalResource); + String parentName = file.getParent().equals("") ? "/" : file.getParent(); + + writer.println("<ul>"); + writer.println("<li><a href=\"../\">" + parentName + "</a> <i><small>(Parent)</small></i></li>"); + writer.println("</ul>"); + } + + writer.println("<ul>"); + } + + private void writeDocumentEnd(PrintWriter writer) + { + writer.println("</ul>"); + writer.println("</body>"); + writer.println("</html>"); + } + + private void writeHyperlinks(PrintWriter writer) + { + for (File file : localResource.listFiles()) + { + writeHyperlink(writer, file.getName(), file.isDirectory()); + } + } + + private void writeHyperlink(PrintWriter writer, String resourceName, boolean directory) + { + if (directory) + { + writer.println("<li><a href=\"./" + resourceName + "/\">" + resourceName + "</a></li>"); + } + else + { + writer.println("<li><a href=\"./" + resourceName + "\">" + resourceName + "</a></li>"); + } + } +} diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/MimeTypes.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/MimeTypes.java index 1219e712e..1df7ae8a5 100644 --- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/MimeTypes.java +++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/MimeTypes.java @@ -1,3 +1,5 @@ +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 @@ -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,8 +19,6 @@ * under the License. */ -package org.apache.maven.archiva.webdav.util; - import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.codehaus.plexus.logging.AbstractLogEnabled; @@ -49,10 +49,9 @@ public class MimeTypes extends AbstractLogEnabled implements Initializable { - /** - * @plexus.configuration default-value="org/apache/maven/archiva/webdav/util/mime-types.txt" - */ - private String resource; + private static final String DEFAULT_MIME_TYPE = "application/octet-stream"; + + private String resource = "org/apache/maven/archiva/webdav/util/mime.types"; private Map mimeMap = new HashMap(); @@ -74,6 +73,13 @@ public class MimeTypes value = (String) mimeMap.get( filename.substring( index + 1 ).toLowerCase() ); } } + + + if (value == null) + { + value = DEFAULT_MIME_TYPE; + } + return value; } diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/RepositoryPathUtil.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/RepositoryPathUtil.java new file mode 100644 index 000000000..368e1a1d7 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/RepositoryPathUtil.java @@ -0,0 +1,105 @@ +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.commons.lang.StringUtils; +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.io.FilenameUtils; + +/** + * @author <a href="mailto:james@atlassian.com">James William Dumay</a> + */ +public class RepositoryPathUtil +{ + public static String getLogicalResource(final String href) + { + String logicalResource = null; + String requestPathInfo = StringUtils.defaultString( href ); + + //remove prefix ie /repository/blah becomes /blah + requestPathInfo = removePrefix(requestPathInfo); + + // Remove prefixing slash as the repository id doesn't contain it; + if ( requestPathInfo.startsWith( "/" ) ) + { + requestPathInfo = requestPathInfo.substring( 1 ); + } + + int slash = requestPathInfo.indexOf( '/' ); + if ( slash > 0 ) + { + logicalResource = requestPathInfo.substring( slash ); + + if (logicalResource.endsWith( "/.." ) ) + { + logicalResource += "/"; + } + + if ( logicalResource != null && logicalResource.startsWith( "//" ) ) + { + logicalResource = logicalResource.substring( 1 ); + } + + if ( logicalResource == null ) + { + logicalResource = "/"; + } + } + else + { + logicalResource = "/"; + } + return logicalResource; + } + + public static String getRepositoryName(final String href) + { + String requestPathInfo = StringUtils.defaultString( href ); + + //remove prefix ie /repository/blah becomes /blah + requestPathInfo = removePrefix(requestPathInfo); + + // 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" + return requestPathInfo.substring( 0, slash ); + } + return requestPathInfo; + } + + private static String removePrefix(final String href) + { + String[] parts = StringUtils.split(href, '/'); + parts = (String[]) ArrayUtils.subarray(parts, 1, parts.length); + if (parts == null || parts.length == 0) + { + return "/"; + } + return StringUtils.join(parts, '/'); + } +} diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/WebdavMethodUtil.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/WebdavMethodUtil.java index a551e8c17..2560b82c3 100644 --- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/WebdavMethodUtil.java +++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/WebdavMethodUtil.java @@ -1,3 +1,5 @@ +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 @@ -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,8 +19,6 @@ * under the License. */ -package org.apache.maven.archiva.webdav.util; - import org.apache.commons.lang.StringUtils; import java.util.ArrayList; diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/WrappedRepositoryRequest.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/WrappedRepositoryRequest.java deleted file mode 100644 index 29ef2f556..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/WrappedRepositoryRequest.java +++ /dev/null @@ -1,184 +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.util; - -import org.apache.commons.lang.StringUtils; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -/** - * RepositoryRequest - wrapped servlet request to adjust the incoming request before the components get it. - * It eliminates the prefix from the pathInfo portion of the URL requested. - * And also allows for Header adjustment. - * - * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a> - * @version $Id: WrappedRepositoryRequest.java 7001 2007-10-23 22:40:14Z joakime $ - */ -public class WrappedRepositoryRequest - extends HttpServletRequestWrapper -{ - private String pathInfo; - - private Map headers; - - /** - * The Date Formats most commonly seen in Request Headers. - */ - private SimpleDateFormat dateFormats[]; - - public WrappedRepositoryRequest( HttpServletRequest request ) - { - super( request ); - - dateFormats = new SimpleDateFormat[] { - new SimpleDateFormat( "EEE, dd MMM yyyy HH:mm:ss zzz" ), - new SimpleDateFormat( "EEE, dd-MMM-yy HH:mm:ss" ), - new SimpleDateFormat( "EEE MMM dd HH:mm:ss yyyy" ) }; - - headers = new HashMap(); - - Enumeration enHeaders = request.getHeaderNames(); - while ( enHeaders.hasMoreElements() ) - { - String name = (String) enHeaders.nextElement(); - String value = request.getHeader( name ); - headers.put( name, value ); - } - } - - public void setHeader( String name, String value ) - { - headers.put( name, value ); - } - - public long getDateHeader( String name ) - { - String value = (String) headers.get( name ); - if ( StringUtils.isEmpty( value ) ) - { - // no value? return -1 - return -1; - } - - // Try most common formats first. - for ( int i = 0; i < dateFormats.length; i++ ) - { - try - { - Date date = (Date) dateFormats[i].parseObject( value ); - return date.getTime(); - } - catch ( java.lang.Exception e ) - { - /* ignore exception */ - } - } - - // Now check for the odd "GMT" formats (hey, it happens) - if ( value.endsWith( " GMT" ) ) - { - value = value.substring( 0, value.length() - 4 ); - - for ( int i = 0; i < dateFormats.length; i++ ) - { - try - { - Date date = (Date) dateFormats[i].parseObject( value ); - return date.getTime(); - } - catch ( java.lang.Exception e ) - { - /* ignore exception */ - } - } - } - - // unrecognized format? return -1 - return -1; - } - - public String getHeader( String name ) - { - return (String) headers.get( name ); - } - - public Enumeration getHeaderNames() - { - return new Enumeration() - { - private Iterator iter = headers.keySet().iterator(); - - public boolean hasMoreElements() - { - return iter.hasNext(); - } - - public Object nextElement() - { - return iter.next(); - } - }; - } - - public int getIntHeader( String name ) - { - String value = getHeader( name ); - try - { - return Integer.parseInt( value ); - } - catch ( NumberFormatException e ) - { - return -1; - } - } - - public void setPathInfo( String alternatePathInfo ) - { - this.pathInfo = alternatePathInfo; - } - - public String getPathInfo() - { - if ( this.pathInfo != null ) - { - return this.pathInfo; - } - - return super.getPathInfo(); - } - - public String getServletPath() - { - if ( this.pathInfo != null ) - { - return super.getServletPath() + "/" + this.pathInfo; - } - - return super.getServletPath(); - } -} diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/betaversion/webdav/DAVServlet.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/betaversion/webdav/DAVServlet.java deleted file mode 100644 index 4b25e84c8..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/betaversion/webdav/DAVServlet.java +++ /dev/null @@ -1,57 +0,0 @@ -/* ========================================================================== * - * Copyright (C) 2004-2006, Pier Fumagalli <http://could.it/> * - * 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 <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.betaversion.webdav; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; - -/** - * <p>The {@link DAVServlet} class has been moved to a new package and should - * now be referred as {@link it.could.webdav.DAVServlet}.</p> - * - * <p>This class will be preserved for some time (not so long) to give people - * time to update their servlet deployment descriptors.</p> - * - * @author <a href="http://could.it/">Pier Fumagalli</a> - * @deprecated This class has been moved into the <code>it.could.webdav</code> - * package. Reconfigure your <code>web.xml</code> deployment - * descriptor to use {@link it.could.webdav.DAVServlet}. - */ -public class DAVServlet extends it.could.webdav.DAVServlet { - - /** - * <p>Create a new {@link DAVServlet} instance.</p> - */ - public DAVServlet() { - super(); - } - - /** - * <p>Initialize this {@link DAVServlet} instance reporting to the - * {@link ServletContext} log that this class is deprecated.</p> - */ - public void init(ServletConfig config) - throws ServletException { - final ServletContext context = config.getServletContext(); - context.log("The class \"" + this.getClass().getName() - + "\" is deprecated"); - context.log("Modify the \"web.xml\" deployment descriptor to use \"" - + it.could.webdav.DAVServlet.class.getName() + "\""); - super.init(config); - } -} diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/betaversion/webdav/package.html b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/betaversion/webdav/package.html deleted file mode 100644 index cdc5bf1ee..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/betaversion/webdav/package.html +++ /dev/null @@ -1,15 +0,0 @@ -<html> - <head> - <title>Could.IT WebDAV Servlet - - -

- This package is deprecated, but preserved to maintain compatibility - with previous versions. -

-

- Please refer to the documentation in the {@link it.could.webdav} package - for the new version description. -

- - diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/resources/org/apache/maven/archiva/webdav/util/mime-types.txt b/archiva-modules/archiva-web/archiva-webdav/src/main/resources/org/apache/maven/archiva/webdav/util/mime-types.txt deleted file mode 100644 index 56ab6f59e..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/main/resources/org/apache/maven/archiva/webdav/util/mime-types.txt +++ /dev/null @@ -1,128 +0,0 @@ -# This is a comment. I love comments. - -# This file controls what Internet media types are sent to the client for -# given file extension(s). Sending the correct media type to the client -# is important so they know how to handle the content of the file. -# Extra types can either be added here or by using an AddType directive -# in your config files. For more information about Internet media types, -# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type -# registry is at . - -# MIME type Extensions - -application/andrew-inset ez -application/atom+xml atom -application/java-archive jar -application/mac-binhex40 hqx -application/mac-compactpro cpt -application/mathml+xml mathml -application/msword doc -application/octet-stream bin dms lha lzh exe class so dll dmg -application/oda oda -application/ogg ogg -application/pdf pdf -application/postscript ai eps ps -application/rdf+xml rdf -application/smil smi smil -application/srgs gram -application/srgs+xml grxml -application/vnd.mif mif -application/vnd.mozilla.xul+xml xul -application/vnd.ms-excel xls -application/vnd.ms-powerpoint ppt -application/vnd.rn-realmedia rm -application/vnd.wap.wbxml wbxml -application/vnd.wap.wmlc wmlc -application/vnd.wap.wmlscriptc wmlsc -application/voicexml+xml vxml -application/x-bcpio bcpio -application/x-cdlink vcd -application/x-chess-pgn pgn -application/x-cpio cpio -application/x-csh csh -application/x-director dcr dir dxr -application/x-dvi dvi -application/x-futuresplash spl -application/x-gtar gtar -application/x-hdf hdf -application/x-java-jnlp-file jnlp -application/x-javascript js -application/x-koan skp skd skt skm -application/x-latex latex -application/x-netcdf nc cdf -application/x-sh sh -application/x-shar shar -application/x-shockwave-flash swf -application/x-stuffit sit -application/x-sv4cpio sv4cpio -application/x-sv4crc sv4crc -application/x-tar tar -application/x-tcl tcl -application/x-tex tex -application/x-texinfo texinfo texi -application/x-troff t tr roff -application/x-troff-man man -application/x-troff-me me -application/x-troff-ms ms -application/x-ustar ustar -application/x-wais-source src -application/xhtml+xml xhtml xht -application/xml xml xsl -application/xml-dtd dtd -application/xslt+xml xslt -application/zip zip -audio/basic au snd -audio/midi mid midi kar -audio/mpeg mpga mp2 mp3 -audio/x-aiff aif aiff aifc -audio/x-mpegurl m3u -audio/x-pn-realaudio ram ra -audio/x-wav wav -chemical/x-pdb pdb -chemical/x-xyz xyz -image/bmp bmp -image/cgm cgm -image/gif gif -image/ief ief -image/jp2 jp2 -image/jpeg jpeg jpg jpe -image/pict pict pic pct -image/png png -image/svg+xml svg -image/tiff tiff tif -image/vnd.djvu djvu djv -image/vnd.wap.wbmp wbmp -image/x-cmu-raster ras -image/x-icon ico -image/x-macpaint pntg pnt mac -image/x-portable-anymap pnm -image/x-portable-bitmap pbm -image/x-portable-graymap pgm -image/x-portable-pixmap ppm -image/x-quicktime qtif qti -image/x-rgb rgb -image/x-xbitmap xbm -image/x-xpixmap xpm -image/x-xwindowdump xwd -model/iges igs iges -model/mesh msh mesh silo -model/vrml wrl vrml -text/calendar ics ifb -text/css css -text/html html htm -text/plain asc txt -text/richtext rtx -text/rtf rtf -text/sgml sgml sgm -text/tab-separated-values tsv -text/vnd.wap.wml wml -text/vnd.wap.wmlscript wmls -text/x-setext etx -video/mp4 mp4 -video/mpeg mpeg mpg mpe -video/quicktime qt mov -video/vnd.mpegurl mxu m4u -video/x-dv dv dif -video/x-msvideo avi -video/x-sgi-movie movie -x-conference/x-cooltalk ice diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/resources/org/apache/maven/archiva/webdav/util/mime.types b/archiva-modules/archiva-web/archiva-webdav/src/main/resources/org/apache/maven/archiva/webdav/util/mime.types new file mode 100644 index 000000000..c479bb54b --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webdav/src/main/resources/org/apache/maven/archiva/webdav/util/mime.types @@ -0,0 +1,127 @@ +# This file controls what Internet media types are sent to the client for +# given file extension(s). Sending the correct media type to the client +# is important so they know how to handle the content of the file. +# Extra types can either be added here or by using an AddType directive +# in your config files. For more information about Internet media types, +# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type +# registry is at . + +# MIME type Extensions + +application/andrew-inset ez +application/atom+xml atom +application/java-archive jar +application/mac-binhex40 hqx +application/mac-compactpro cpt +application/mathml+xml mathml +application/msword doc +application/octet-stream bin dms lha lzh exe class so dll dmg +application/oda oda +application/ogg ogg +application/pdf pdf +application/pgp-encrypted pgp +application/postscript ai eps ps +application/rdf+xml rdf +application/smil smi smil +application/srgs gram +application/srgs+xml grxml +application/vnd.mif mif +application/vnd.mozilla.xul+xml xul +application/vnd.ms-excel xls +application/vnd.ms-powerpoint ppt +application/vnd.rn-realmedia rm +application/vnd.wap.wbxml wbxml +application/vnd.wap.wmlc wmlc +application/vnd.wap.wmlscriptc wmlsc +application/voicexml+xml vxml +application/x-bcpio bcpio +application/x-cdlink vcd +application/x-chess-pgn pgn +application/x-cpio cpio +application/x-csh csh +application/x-director dcr dir dxr +application/x-dvi dvi +application/x-futuresplash spl +application/x-gtar gtar +application/x-hdf hdf +application/x-java-jnlp-file jnlp +application/x-javascript js +application/x-koan skp skd skt skm +application/x-latex latex +application/x-netcdf nc cdf +application/x-sh sh +application/x-shar shar +application/x-shockwave-flash swf +application/x-stuffit sit +application/x-sv4cpio sv4cpio +application/x-sv4crc sv4crc +application/x-tar tar +application/x-tcl tcl +application/x-tex tex +application/x-texinfo texinfo texi +application/x-troff t tr roff +application/x-troff-man man +application/x-troff-me me +application/x-troff-ms ms +application/x-ustar ustar +application/x-wais-source src +application/xhtml+xml xhtml xht +application/xml xml xsl pom +application/xml-dtd dtd +application/xslt+xml xslt +application/zip zip +audio/basic au snd +audio/midi mid midi kar +audio/mpeg mpga mp2 mp3 +audio/x-aiff aif aiff aifc +audio/x-mpegurl m3u +audio/x-pn-realaudio ram ra +audio/x-wav wav +chemical/x-pdb pdb +chemical/x-xyz xyz +image/bmp bmp +image/cgm cgm +image/gif gif +image/ief ief +image/jp2 jp2 +image/jpeg jpeg jpg jpe +image/pict pict pic pct +image/png png +image/svg+xml svg +image/tiff tiff tif +image/vnd.djvu djvu djv +image/vnd.wap.wbmp wbmp +image/x-cmu-raster ras +image/x-icon ico +image/x-macpaint pntg pnt mac +image/x-portable-anymap pnm +image/x-portable-bitmap pbm +image/x-portable-graymap pgm +image/x-portable-pixmap ppm +image/x-quicktime qtif qti +image/x-rgb rgb +image/x-xbitmap xbm +image/x-xpixmap xpm +image/x-xwindowdump xwd +model/iges igs iges +model/mesh msh mesh silo +model/vrml wrl vrml +text/calendar ics ifb +text/css css +text/html html htm +text/plain asc txt sha1 md5 +text/richtext rtx +text/rtf rtf +text/sgml sgml sgm +text/tab-separated-values tsv +text/vnd.wap.wml wml +text/vnd.wap.wmlscript wmls +text/x-setext etx +video/mp4 mp4 +video/mpeg mpeg mpg mpe +video/quicktime qt mov +video/vnd.mpegurl mxu m4u +video/x-dv dv dif +video/x-msvideo avi +video/x-sgi-movie movie +x-conference/x-cooltalk ice diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/resources/plexus-webdav/mime.types b/archiva-modules/archiva-web/archiva-webdav/src/main/resources/plexus-webdav/mime.types deleted file mode 100644 index 5baed56f7..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/main/resources/plexus-webdav/mime.types +++ /dev/null @@ -1,127 +0,0 @@ -# This is a comment. I love comments. - -# This file controls what Internet media types are sent to the client for -# given file extension(s). Sending the correct media type to the client -# is important so they know how to handle the content of the file. -# Extra types can either be added here or by using an AddType directive -# in your config files. For more information about Internet media types, -# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type -# registry is at . - -# MIME type Extensions - -application/andrew-inset ez -application/atom+xml atom -application/mac-binhex40 hqx -application/mac-compactpro cpt -application/mathml+xml mathml -application/msword doc -application/octet-stream bin dms lha lzh exe class so dll dmg -application/oda oda -application/ogg ogg -application/pdf pdf -application/postscript ai eps ps -application/rdf+xml rdf -application/smil smi smil -application/srgs gram -application/srgs+xml grxml -application/vnd.mif mif -application/vnd.mozilla.xul+xml xul -application/vnd.ms-excel xls -application/vnd.ms-powerpoint ppt -application/vnd.rn-realmedia rm -application/vnd.wap.wbxml wbxml -application/vnd.wap.wmlc wmlc -application/vnd.wap.wmlscriptc wmlsc -application/voicexml+xml vxml -application/x-bcpio bcpio -application/x-cdlink vcd -application/x-chess-pgn pgn -application/x-cpio cpio -application/x-csh csh -application/x-director dcr dir dxr -application/x-dvi dvi -application/x-futuresplash spl -application/x-gtar gtar -application/x-hdf hdf -application/x-java-jnlp-file jnlp -application/x-javascript js -application/x-koan skp skd skt skm -application/x-latex latex -application/x-netcdf nc cdf -application/x-sh sh -application/x-shar shar -application/x-shockwave-flash swf -application/x-stuffit sit -application/x-sv4cpio sv4cpio -application/x-sv4crc sv4crc -application/x-tar tar -application/x-tcl tcl -application/x-tex tex -application/x-texinfo texinfo texi -application/x-troff t tr roff -application/x-troff-man man -application/x-troff-me me -application/x-troff-ms ms -application/x-ustar ustar -application/x-wais-source src -application/xhtml+xml xhtml xht -application/xml xml xsl -application/xml-dtd dtd -application/xslt+xml xslt -application/zip zip -audio/basic au snd -audio/midi mid midi kar -audio/mpeg mpga mp2 mp3 -audio/x-aiff aif aiff aifc -audio/x-mpegurl m3u -audio/x-pn-realaudio ram ra -audio/x-wav wav -chemical/x-pdb pdb -chemical/x-xyz xyz -image/bmp bmp -image/cgm cgm -image/gif gif -image/ief ief -image/jp2 jp2 -image/jpeg jpeg jpg jpe -image/pict pict pic pct -image/png png -image/svg+xml svg -image/tiff tiff tif -image/vnd.djvu djvu djv -image/vnd.wap.wbmp wbmp -image/x-cmu-raster ras -image/x-icon ico -image/x-macpaint pntg pnt mac -image/x-portable-anymap pnm -image/x-portable-bitmap pbm -image/x-portable-graymap pgm -image/x-portable-pixmap ppm -image/x-quicktime qtif qti -image/x-rgb rgb -image/x-xbitmap xbm -image/x-xpixmap xpm -image/x-xwindowdump xwd -model/iges igs iges -model/mesh msh mesh silo -model/vrml wrl vrml -text/calendar ics ifb -text/css css -text/html html htm -text/plain asc txt -text/richtext rtx -text/rtf rtf -text/sgml sgml sgm -text/tab-separated-values tsv -text/vnd.wap.wml wml -text/vnd.wap.wmlscript wmls -text/x-setext etx -video/mp4 mp4 -video/mpeg mpeg mpg mpe -video/quicktime qt mov -video/vnd.mpegurl mxu m4u -video/x-dv dv dif -video/x-msvideo avi -video/x-sgi-movie movie -x-conference/x-cooltalk ice diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/resources/plexus-webdav/webdav.props b/archiva-modules/archiva-web/archiva-webdav/src/main/resources/plexus-webdav/webdav.props deleted file mode 100644 index 815c14baf..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/main/resources/plexus-webdav/webdav.props +++ /dev/null @@ -1,13 +0,0 @@ -# -# A simple property file defining some strings that will be returned and/or -# used by the Could.IT DAVServlet at different stages of processing -# - -# Returned by DAVServlet in the "getServletInfo()" method -servlet.information = Could.IT WebDAV Servlet - -# Added to the "Server" header every time a request is processed -servlet.signature = CouldIT-WebDAV - -# Version used in build files and combined to information and signature -version = 0.5-dev diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/TestableHttpServletRequest.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/TestableHttpServletRequest.java deleted file mode 100644 index f214139db..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/TestableHttpServletRequest.java +++ /dev/null @@ -1,495 +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.commons.lang.NotImplementedException; - -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletInputStream; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.MalformedURLException; -import java.net.URL; -import java.security.Principal; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Locale; -import java.util.Map; - -/** - * TestableHttpServletRequest - * - * @author Joakim Erdfelt - * @version $Id: TestableHttpServletRequest.java 6940 2007-10-16 01:02:02Z joakime $ - */ -public class TestableHttpServletRequest - implements HttpServletRequest -{ - - public TestableHttpServletRequest() - { - setDefaults(); - } - - public void setDefaults() - { - authType = null; - scheme = "http"; - protocol = "HTTP/1.1"; - serverName = "localhost"; - serverPort = 80; - remoteHost = "localhost"; - } - - private String authType; - - private String characterEncoding; - - private int contentLength; - - private String contentType; - - private String contextPath; - - private Locale locale; - - private String method; - - private String pathInfo; - - private String pathTranslated; - - private String protocol; - - private String queryString; - - private String remoteAddr; - - private String remoteHost; - - private String remoteUser; - - private String requestedSessionId; - - private boolean requestedSessionIdFromCookie; - - private boolean requestedSessionIdFromUrl; - - private boolean requestedSessionIdValid; - - private StringBuffer requestURL; - - private String scheme; - - private boolean secure; - - private String serverName; - - private int serverPort; - - private String servletPath; - - public Object getAttribute( String name ) - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".getAttribute(String)" ) ); - } - - public Enumeration getAttributeNames() - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".getAttributeNames()" ) ); - } - - public String getAuthType() - { - return authType; - } - - public String getCharacterEncoding() - { - return characterEncoding; - } - - public int getContentLength() - { - return contentLength; - } - - public String getContentType() - { - return contentType; - } - - public String getContextPath() - { - return contextPath; - } - - public Cookie[] getCookies() - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".getCookies()" ) ); - } - - public long getDateHeader( String name ) - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".getDateHeader(String)" ) ); - } - - public String getHeader( String name ) - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".getHeader(String)" ) ); - } - - private Map headers = new HashMap(); - - public Enumeration getHeaderNames() - { - return new IterEnumeration( headers.keySet().iterator() ); - } - - public Enumeration getHeaders( String name ) - { - throw new NotImplementedException( notImplemented( ".getHeaders(String)" ) ); - } - - public ServletInputStream getInputStream() - throws IOException - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".getInputStream()" ) ); - } - - public int getIntHeader( String name ) - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".getIntHeader(String)" ) ); - } - - public Locale getLocale() - { - return locale; - } - - public Enumeration getLocales() - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".getLocales()" ) ); - } - - public String getMethod() - { - return method; - } - - public String getParameter( String name ) - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".getParameter(String)" ) ); - } - - public Map getParameterMap() - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".getParameterMap()" ) ); - } - - public Enumeration getParameterNames() - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".getParameterNames()" ) ); - } - - public String[] getParameterValues( String name ) - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".getParameterValues(String)" ) ); - } - - public String getPathInfo() - { - return pathInfo; - } - - public String getPathTranslated() - { - return pathTranslated; - } - - public String getProtocol() - { - return protocol; - } - - public String getQueryString() - { - return queryString; - } - - public BufferedReader getReader() - throws IOException - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".getReader()" ) ); - } - - public String getRealPath( String path ) - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".getRealPath(String)" ) ); - } - - public String getRemoteAddr() - { - return remoteAddr; - } - - public String getRemoteHost() - { - return remoteHost; - } - - public String getRemoteUser() - { - return remoteUser; - } - - public RequestDispatcher getRequestDispatcher( String path ) - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".getRequestDispatcher(String)" ) ); - } - - public String getRequestedSessionId() - { - return requestedSessionId; - } - - public String getRequestURI() - { - return requestURL.toString(); - } - - public StringBuffer getRequestURL() - { - return requestURL; - } - - public String getScheme() - { - return scheme; - } - - public String getServerName() - { - return serverName; - } - - public int getServerPort() - { - return serverPort; - } - - public String getServletPath() - { - return servletPath; - } - - public HttpSession getSession() - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".getSession()" ) ); - } - - public HttpSession getSession( boolean create ) - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".getSession(boolean)" ) ); - } - - public Principal getUserPrincipal() - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".getUserPrincipal()" ) ); - } - - public boolean isRequestedSessionIdFromCookie() - { - return requestedSessionIdFromCookie; - } - - public boolean isRequestedSessionIdFromUrl() - { - return requestedSessionIdFromUrl; - } - - public boolean isRequestedSessionIdFromURL() - { - return requestedSessionIdFromUrl; - } - - public boolean isRequestedSessionIdValid() - { - return requestedSessionIdValid; - } - - public boolean isSecure() - { - return secure; - } - - public boolean isUserInRole( String role ) - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".isUserInRole(String)" ) ); - } - - public void removeAttribute( String name ) - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".removeAttribute(String)" ) ); - } - - public void setAttribute( String name, Object o ) - { - // TODO: Implement if needed. - throw new NotImplementedException( notImplemented( ".setAttribute(String, Object)" ) ); - } - - public void setCharacterEncoding( String encoding ) - throws UnsupportedEncodingException - { - this.characterEncoding = encoding; - } - - public void setContentLength( int contentLength ) - { - this.contentLength = contentLength; - } - - public void setContentType( String contentType ) - { - this.contentType = contentType; - } - - public void setContextPath( String contextPath ) - { - this.contextPath = contextPath; - } - - public void setMethod( String method ) - { - this.method = method; - } - - public void setPathInfo( String pathInfo ) - { - this.pathInfo = pathInfo; - } - - public void setProtocol( String protocol ) - { - this.protocol = protocol; - } - - public void setQueryString( String queryString ) - { - this.queryString = queryString; - } - - public void setScheme( String scheme ) - { - this.scheme = scheme; - } - - public void setSecure( boolean secure ) - { - this.secure = secure; - } - - public void setServerName( String serverName ) - { - this.serverName = serverName; - } - - public void setServerPort( int serverPort ) - { - this.serverPort = serverPort; - } - - public void setServletPath( String servletPath ) - { - this.servletPath = servletPath; - } - - public void setUrl( String urlString ) - throws MalformedURLException - { - URL url = new URL( urlString ); - this.queryString = url.getQuery(); - this.scheme = url.getProtocol(); - this.serverName = url.getHost(); - this.serverPort = url.getPort(); - - String path = url.getPath(); - if ( !path.startsWith( this.servletPath ) ) - { - throw new MalformedURLException( "Unable to operate on request path [" + path - + "] outside of servletPath [" + this.servletPath + "]." ); - } - - this.pathInfo = path.substring( this.servletPath.length() ); - this.requestURL = new StringBuffer( this.pathInfo ); - } - - private String notImplemented( String msg ) - { - return msg + " is not implemented in " + this.getClass().getName(); - } - - class IterEnumeration - implements Enumeration - { - private Iterator iter; - - public IterEnumeration( Iterator it ) - { - this.iter = it; - } - - public boolean hasMoreElements() - { - return this.iter.hasNext(); - } - - public Object nextElement() - { - return this.iter.next(); - } - } -} diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/servlet/multiplexed/MultiplexedDavServerRequestTest.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/servlet/multiplexed/MultiplexedDavServerRequestTest.java deleted file mode 100644 index 62719cfdb..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/servlet/multiplexed/MultiplexedDavServerRequestTest.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.multiplexed; - -import junit.framework.TestCase; -import org.apache.maven.archiva.webdav.TestableHttpServletRequest; -import org.apache.maven.archiva.webdav.util.WrappedRepositoryRequest; - -import java.net.MalformedURLException; - -/** - * MultiplexedDavServerRequestTest - * - * @author Joakim Erdfelt - * @version $Id: MultiplexedDavServerRequestTest.java 6940 2007-10-16 01:02:02Z joakime $ - */ -public class MultiplexedDavServerRequestTest - extends TestCase -{ - private void assertMultiURL( String expectedPrefix, String expectedLogicalResource, String url ) - throws MalformedURLException - { - TestableHttpServletRequest testrequest = new TestableHttpServletRequest(); - testrequest.setMethod( "GET" ); - testrequest.setServletPath( "/repository" ); - testrequest.setUrl( url ); - - WrappedRepositoryRequest wraprequest = new WrappedRepositoryRequest( testrequest ); - MultiplexedDavServerRequest multirequest = new MultiplexedDavServerRequest( wraprequest ); - - assertEquals( expectedPrefix, multirequest.getPrefix() ); - assertEquals( expectedLogicalResource, multirequest.getLogicalResource() ); - } - - public void testNormalUsage() - throws MalformedURLException - { - assertMultiURL( "corporate", "/", "http://localhost:9091/repository/corporate" ); - assertMultiURL( "corporate", "/dom4j/dom4j/1.4", "http://localhost:9091/repository/corporate/dom4j/dom4j/1.4" ); - } - - public void testHacker() - throws MalformedURLException - { - assertMultiURL( "corporate", "/etc/passwd", "http://localhost:9091/repository/corporate//etc/passwd" ); - // Since the double ".." puts the path outside of the /corporate/, it will return "/" as a hack fallback. - assertMultiURL( "corporate", "/", "http://localhost:9091/repository/corporate/dom4j/../../etc/passwd" ); - assertMultiURL( "corporate", "/", "http://localhost:9091/repository/corporate/../.." ); - } -} diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/simple/SimpleDavServerComponentBasicTest.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/simple/SimpleDavServerComponentBasicTest.java deleted file mode 100644 index 801c59bdf..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/simple/SimpleDavServerComponentBasicTest.java +++ /dev/null @@ -1,38 +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 org.apache.maven.archiva.webdav.test.AbstractBasicWebdavProviderTestCase; - -/** - * SimpleDavServerComponentBasicTest - * - * @author Joakim Erdfelt - * @version $Id: SimpleDavServerComponentBasicTest.java 5408 2007-01-12 19:42:37Z joakime $ - */ -public class SimpleDavServerComponentBasicTest - extends AbstractBasicWebdavProviderTestCase -{ - public SimpleDavServerComponentBasicTest() - { - super(); - setProviderHint( "simple" ); - } -} diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/simple/SimpleDavServerComponentIndexHtmlTest.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/simple/SimpleDavServerComponentIndexHtmlTest.java deleted file mode 100644 index c51b05a5b..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/simple/SimpleDavServerComponentIndexHtmlTest.java +++ /dev/null @@ -1,38 +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 org.apache.maven.archiva.webdav.test.AbstractWebdavIndexHtmlTestCase; - -/** - * SimpleDavServerComponentIndexHtmlTest - * - * @author Joakim Erdfelt - * @version $Id: SimpleDavServerComponentIndexHtmlTest.java 6000 2007-03-04 22:01:49Z joakime $ - */ -public class SimpleDavServerComponentIndexHtmlTest - extends AbstractWebdavIndexHtmlTestCase -{ - public SimpleDavServerComponentIndexHtmlTest() - { - super(); - setProviderHint( "simple" ); - } -} diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/simple/SimpleDavServerComponentMultiTest.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/simple/SimpleDavServerComponentMultiTest.java deleted file mode 100644 index bb17ca8ef..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/simple/SimpleDavServerComponentMultiTest.java +++ /dev/null @@ -1,38 +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 org.apache.maven.archiva.webdav.test.AbstractMultiWebdavProviderTestCase; - -/** - * SimpleDavServerComponentCrossTest - * - * @author Joakim Erdfelt - * @version $Id: SimpleDavServerComponentMultiTest.java 5408 2007-01-12 19:42:37Z joakime $ - */ -public class SimpleDavServerComponentMultiTest - extends AbstractMultiWebdavProviderTestCase -{ - public SimpleDavServerComponentMultiTest() - { - super(); - setProviderHint( "simple" ); - } -} diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/simple/SimpleWebdavServer.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/simple/SimpleWebdavServer.java deleted file mode 100644 index 33ae965c5..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/simple/SimpleWebdavServer.java +++ /dev/null @@ -1,50 +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 org.apache.maven.archiva.webdav.test.AbstractWebdavServer; - -/** - * SimpleWebdavServer - * - * @author Joakim Erdfelt - * @version $Id: SimpleWebdavServer.java 5379 2007-01-07 22:54:41Z joakime $ - */ -public class SimpleWebdavServer - extends AbstractWebdavServer -{ - public static void main( String[] args ) - { - try - { - SimpleWebdavServer server = new SimpleWebdavServer(); - server.startServer(); - } - catch ( Exception e ) - { - e.printStackTrace(); - } - } - - protected String getProviderHint() - { - return "simple"; - } -} diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/AbstractBasicWebdavProviderTestCase.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/AbstractBasicWebdavProviderTestCase.java deleted file mode 100644 index 82eab6cf8..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/AbstractBasicWebdavProviderTestCase.java +++ /dev/null @@ -1,255 +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.test; - -import org.apache.commons.httpclient.HttpURL; -import org.apache.maven.archiva.webdav.servlet.basic.BasicWebDavServlet; -import org.apache.webdav.lib.WebdavResource; -import org.codehaus.plexus.util.IOUtil; -import org.mortbay.jetty.Server; -import org.mortbay.jetty.servlet.ServletHandler; -import org.mortbay.jetty.servlet.ServletHolder; -import org.mortbay.jetty.webapp.WebAppContext; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; - -/** - * AbstractBasicWebdavProviderTestCase - * - * @author Joakim Erdfelt - * @version $Id: AbstractBasicWebdavProviderTestCase.java 6000 2007-03-04 22:01:49Z joakime $ - */ -public abstract class AbstractBasicWebdavProviderTestCase - extends AbstractWebdavProviderTestCase -{ - private File serverRepoDir; - - private WebdavResource davRepo; - - /** The Jetty Server. */ - private Server server; - - protected void setUp() - throws Exception - { - super.setUp(); - - // Initialize server contents directory. - - serverRepoDir = getTestDir( "sandbox" ); - - // Setup the Jetty Server. - - System.setProperty( "DEBUG", "" ); - System.setProperty( "org.mortbay.log.class", "org.slf4j.impl.SimpleLogger" ); - - server = new Server( PORT ); - WebAppContext webAppConfig = new WebAppContext( server, getTestFile( "src/test/webapp" ).getCanonicalPath(), "/" ); - - ServletHandler servletHandler = webAppConfig.getServletHandler(); - - ServletHolder holder = servletHandler.addServletWithMapping( BasicWebDavServlet.class, CONTEXT + "/*" ); - - holder.setInitParameter( "dav.root", serverRepoDir.getAbsolutePath() ); - - server.start(); - - // Setup Client Side - - HttpURL httpSandboxUrl = new HttpURL( "http://localhost:" + PORT + CONTEXT + "/" ); - - try - { - davRepo = new WebdavResource( httpSandboxUrl ); - - davRepo.setDebug( 8 ); - - davRepo.setPath( CONTEXT ); - } - catch ( IOException e ) - { - tearDown(); - throw e; - } - } - - protected void tearDown() - throws Exception - { - serverRepoDir = null; - - if ( server != null ) - { - try - { - server.stop(); - } - catch ( Exception e ) - { - /* ignore */ - } - server = null; - } - - if ( davRepo != null ) - { - try - { - davRepo.close(); - } - catch ( Exception e ) - { - /* ignore */ - } - - davRepo = null; - } - - super.tearDown(); - } - - // -------------------------------------------------------------------- - // Actual Test Cases. - // -------------------------------------------------------------------- - - public void testPutGet() - throws Exception - { - // Quote: Rocky - String contents = "yo!\n"; - - assertDavTouchFile( davRepo, CONTEXT, "data.txt", contents ); - - InputStream inputStream = davRepo.getMethodData( CONTEXT + "/data.txt" ); - - assertEquals( contents, IOUtil.toString( inputStream ) ); - } - - public void testCollectionTasks() - throws Exception - { - // Create a few collections. - assertDavMkDir( davRepo, CONTEXT + "/bar" ); - assertDavMkDir( davRepo, CONTEXT + "/bar/foo" ); - - // Remove a collection - davRepo.setPath( CONTEXT ); - if ( !davRepo.deleteMethod( CONTEXT + "/bar/foo" ) ) - { - fail( "Unable to remove <" + CONTEXT + "/bar/foo> on <" + davRepo.getHttpURL().toString() + "> due to <" - + davRepo.getStatusMessage() + ">" ); - } - - assertDavDirNotExists( davRepo, CONTEXT + "/bar/foo" ); - } - - public void testResourceCopy() - throws Exception - { - // Lyrics: Cool and the Gang - Celebrate Good Times - String contents = "we're gonna have a good time tonite. lets celebrate. it's a celebration. " - + "cel-e-brate good times, come on!"; - - // Create a few collections. - assertDavMkDir( davRepo, CONTEXT + "/bar" ); - assertDavMkDir( davRepo, CONTEXT + "/foo" ); - - // Create a resource - assertDavTouchFile( davRepo, CONTEXT + "/bar", "data.txt", contents ); - - // Test for existance of resource - assertDavFileExists( davRepo, CONTEXT + "/bar", "data.txt" ); - assertDavFileNotExists( davRepo, CONTEXT + "/foo", "data.txt" ); - - // Copy resource - String source = CONTEXT + "/bar/data.txt"; - String dest = CONTEXT + "/foo/data.txt"; - if ( !davRepo.copyMethod( source, dest ) ) - { - fail( "Unable to copy <" + source + "> to <" + dest + "> on <" + davRepo.getHttpURL().toString() - + "> due to <" + davRepo.getStatusMessage() + ">" ); - } - - // Test for existance of resource - assertDavFileExists( davRepo, CONTEXT + "/bar", "data.txt" ); - assertDavFileExists( davRepo, CONTEXT + "/foo", "data.txt" ); - } - - public void testResourceMove() - throws Exception - { - // Lyrics: Men At Work - Who Can It Be Now - String contents = "Who can it be knocking at my door?\n" + "Make no sound, tip-toe across the floor.\n" - + "If he hears, he'll knock all day,\n" + "I'll be trapped, and here I'll have to stay.\n" - + "I've done no harm, I keep to myself;\n" + "There's nothing wrong with my state of mental health.\n" - + "I like it here with my childhood friend;\n" + "Here they come, those feelings again!\n"; - - // Create a few collections. - assertDavMkDir( davRepo, CONTEXT + "/bar" ); - assertDavMkDir( davRepo, CONTEXT + "/foo" ); - - // Create a resource - assertDavTouchFile( davRepo, CONTEXT + "/bar", "data.txt", contents ); - - // Test for existance of resource - assertDavFileExists( davRepo, CONTEXT + "/bar", "data.txt" ); - assertDavFileNotExists( davRepo, CONTEXT + "/foo", "data.txt" ); - - // Copy resource - String source = CONTEXT + "/bar/data.txt"; - String dest = CONTEXT + "/foo/data.txt"; - if ( !davRepo.moveMethod( source, dest ) ) - { - fail( "Unable to move <" + source + "> to <" + dest + "> on <" + davRepo.getHttpURL().toString() - + "> due to <" + davRepo.getStatusMessage() + ">" ); - } - - // Test for existance of resource - assertDavFileNotExists( davRepo, CONTEXT + "/bar", "data.txt" ); - assertDavFileExists( davRepo, CONTEXT + "/foo", "data.txt" ); - } - - public void testResourceDelete() - throws Exception - { - // Lyrics: Men At Work - Down Under - String contents = "Lying in a den in Bombay\n" + "With a slack jaw, and not much to say\n" - + "I said to the man, \"Are you trying to tempt me\"\n" + "Because I come from the land of plenty?\n"; - - // Create a few collections. - assertDavMkDir( davRepo, CONTEXT + "/bar" ); - - // Create a resource - assertDavTouchFile( davRepo, CONTEXT + "/bar", "data.txt", contents ); - - // Move resource - davRepo.setPath( CONTEXT ); - if ( !davRepo.deleteMethod( CONTEXT + "/bar/data.txt" ) ) - { - fail( "Unable to remove <" + CONTEXT + "/bar/data.txt> on <" + davRepo.getHttpURL().toString() - + "> due to <" + davRepo.getStatusMessage() + ">" ); - } - - // Test for existance via webdav interface. - assertDavFileNotExists( davRepo, CONTEXT + "/bar", "data.txt" ); - } -} diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/AbstractMultiWebdavProviderTestCase.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/AbstractMultiWebdavProviderTestCase.java deleted file mode 100644 index 71d2d46c0..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/AbstractMultiWebdavProviderTestCase.java +++ /dev/null @@ -1,203 +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.test; - -import org.apache.commons.httpclient.HttpStatus; -import org.apache.commons.httpclient.HttpURL; -import org.apache.webdav.lib.WebdavResource; -import org.mortbay.jetty.Server; -import org.mortbay.jetty.servlet.ServletHandler; -import org.mortbay.jetty.servlet.ServletHolder; -import org.mortbay.jetty.webapp.WebAppContext; - -import java.io.File; -import java.io.IOException; - -/** - * AbstractMultiWebdavProviderTestCase - * - * @author Joakim Erdfelt - * @version $Id: AbstractMultiWebdavProviderTestCase.java 5997 2007-03-04 19:41:15Z joakime $ - */ -public abstract class AbstractMultiWebdavProviderTestCase - extends AbstractWebdavProviderTestCase -{ - File serverSandboxDir; - - File serverSnapshotsDir; - - /** The Jetty Server. */ - private Server server; - - private WebdavResource davSnapshots; - - private WebdavResource davSandbox; - - protected void setUp() - throws Exception - { - super.setUp(); - - // Initialize server contents directory. - - serverSandboxDir = getTestDir( "sandbox" ); - serverSnapshotsDir = getTestDir( "snapshots" ); - - // Setup the Jetty Server. - - System.setProperty( "DEBUG", "" ); - System.setProperty( "org.mortbay.log.class", "org.slf4j.impl.SimpleLogger" ); - - server = new Server( PORT ); - - WebAppContext webAppConfig = new WebAppContext( server, getTestFile( "src/test/webapp" ).getCanonicalPath(), "/" ); - ServletHandler servletHandler = webAppConfig.getServletHandler(); - - ServletHolder holder = servletHandler.addServletWithMapping( TestMultiWebDavServlet.class, CONTEXT + "/*" ); - holder.setInitParameter( "root.sandbox", serverSandboxDir.getAbsolutePath() ); - holder.setInitParameter( "root.snapshots", serverSnapshotsDir.getAbsolutePath() ); - - System.out.println( "root.sandbox = " + serverSandboxDir.getAbsolutePath() ); - System.out.println( "root.snapshots = " + serverSnapshotsDir.getAbsolutePath() ); - - server.start(); - - // Setup Client Side - - HttpURL httpSandboxUrl = new HttpURL( "http://localhost:" + PORT + CONTEXT + "/sandbox/" ); - HttpURL httpSnapshotsUrl = new HttpURL( "http://localhost:" + PORT + CONTEXT + "/snapshots/" ); - - try - { - davSandbox = new WebdavResource( httpSandboxUrl ); - davSnapshots = new WebdavResource( httpSnapshotsUrl ); - - davSandbox.setDebug( 8 ); - davSnapshots.setDebug( 8 ); - - davSandbox.setPath( CONTEXT + "/sandbox/" ); - davSnapshots.setPath( CONTEXT + "/snapshots/" ); - } - catch ( IOException e ) - { - tearDown(); - throw e; - } - } - - protected void tearDown() - throws Exception - { - serverRootDir = null; - - if ( server != null ) - { - try - { - server.stop(); - } - catch ( Exception e ) - { - /* ignore */ - } - server = null; - } - - if ( davSandbox != null ) - { - try - { - davSandbox.close(); - } - catch ( Exception e ) - { - /* ignore */ - } - - davSandbox = null; - } - - if ( davSnapshots != null ) - { - try - { - davSnapshots.close(); - } - catch ( Exception e ) - { - /* ignore */ - } - - davSnapshots = null; - } - - super.tearDown(); - } - - public void testResourceMoveCrossWebdav() - throws Exception - { - // Create a few collections. - assertDavMkDir( davSandbox, CONTEXT + "/sandbox/bar" ); - assertDavMkDir( davSnapshots, CONTEXT + "/snapshots/foo" ); - - // Create a resource - assertDavTouchFile( davSandbox, CONTEXT + "/sandbox/bar", "data.txt", "yo!" ); - - // Move resource URL to URL (Across the WebDav Servlets) - davSandbox.setPath( CONTEXT + "/sandbox/bar" ); - String source = CONTEXT + "/sandbox/bar/data.txt"; - String dest = "http://localhost:" + PORT + CONTEXT + "/snapshots/foo/data.txt"; - if ( !davSandbox.moveMethod( source, dest ) ) - { - // TODO: remove when fully implemented. - if ( davSandbox.getStatusCode() == HttpStatus.SC_NOT_IMPLEMENTED ) - { - // return quietly, as the server reported no support for this method. - return; - } - - fail( "Unable to move <" + source + "> to <" + dest + "> on <" + davSandbox.getHttpURL().toString() - + "> due to <" + davSandbox.getStatusMessage() + ">" ); - } - - assertDavFileNotExists( davSandbox, CONTEXT + "/sandbox/bar", "data.txt" ); - assertDavFileExists( davSnapshots, CONTEXT + "/snapshots/foo", "data.txt" ); - } - - public void testResourceDoesNotExist() - throws Exception - { - // Create a few collections. - assertDavMkDir( davSandbox, CONTEXT + "/sandbox/bar" ); - assertDavMkDir( davSnapshots, CONTEXT + "/snapshots/foo" ); - - // Create a resource - assertDavTouchFile( davSandbox, CONTEXT + "/sandbox/bar", "data.txt", "yo!" ); - - // Get bad resources URLs - String urlPrefix = "http://localhost:" + PORT + CONTEXT; - assertGet404( urlPrefix + "/sandbox/a/resource/that/does/not/exist.html" ); - assertGet404( urlPrefix + "/" ); - assertGet404( urlPrefix + "/snapshots/foo/index.html" ); - assertGet404( urlPrefix + "/sandbox/bar.html" ); - assertGet404( urlPrefix + "/nonexistant/index.html" ); - } -} diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/AbstractWebdavIndexHtmlTestCase.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/AbstractWebdavIndexHtmlTestCase.java deleted file mode 100644 index f01790430..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/AbstractWebdavIndexHtmlTestCase.java +++ /dev/null @@ -1,148 +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.test; - -import org.apache.commons.httpclient.HttpURL; -import org.apache.maven.archiva.webdav.servlet.basic.BasicWebDavServlet; -import org.apache.webdav.lib.WebdavResource; -import org.mortbay.jetty.Server; -import org.mortbay.jetty.servlet.ServletHandler; -import org.mortbay.jetty.servlet.ServletHolder; -import org.mortbay.jetty.webapp.WebAppContext; - -import java.io.File; -import java.io.IOException; - -public abstract class AbstractWebdavIndexHtmlTestCase - extends AbstractWebdavProviderTestCase -{ - private File serverRepoDir; - - private WebdavResource davRepo; - - /** The Jetty Server. */ - private Server server; - - protected void setUp() - throws Exception - { - super.setUp(); - - // Initialize server contents directory. - - serverRepoDir = getTestDir( "sandbox" ); - - // Setup the Jetty Server. - - System.setProperty( "DEBUG", "" ); - System.setProperty( "org.mortbay.log.class", "org.slf4j.impl.SimpleLogger" ); - - server = new Server( PORT ); - WebAppContext webAppConfig = new WebAppContext( server, getTestFile( "src/test/webapp" ).getCanonicalPath(), "/" ); - - ServletHandler servletHandler = webAppConfig.getServletHandler(); - - ServletHolder holder = servletHandler.addServletWithMapping( BasicWebDavServlet.class, CONTEXT + "/*" ); - - holder.setInitParameter( BasicWebDavServlet.INIT_ROOT_DIRECTORY, serverRepoDir.getAbsolutePath() ); - holder.setInitParameter( BasicWebDavServlet.INIT_USE_INDEX_HTML, "true" ); - - server.start(); - - // Setup Client Side - - HttpURL httpSandboxUrl = new HttpURL( "http://localhost:" + PORT + CONTEXT + "/" ); - - try - { - davRepo = new WebdavResource( httpSandboxUrl ); - - davRepo.setDebug( 8 ); - - davRepo.setPath( CONTEXT ); - } - catch ( IOException e ) - { - tearDown(); - throw e; - } - } - - protected void tearDown() - throws Exception - { - serverRepoDir = null; - - if ( server != null ) - { - try - { - server.stop(); - } - catch ( Exception e ) - { - /* ignore */ - } - server = null; - } - - if ( davRepo != null ) - { - try - { - davRepo.close(); - } - catch ( Exception e ) - { - /* ignore */ - } - - davRepo = null; - } - - super.tearDown(); - } - - public void testCollectionIndexHtml() - throws Exception - { - // Lyrics: Colin Hay - Overkill - String contents = "I cant get to sleep\n" + "I think about the implications\n" + "Of diving in too deep\n" - + "And possibly the complications\n" + "Especially at night\n" + "I worry over situations\n" - + "I know will be alright\n" + "Perahaps its just my imagination\n" + "Day after day it reappears\n" - + "Night after night my heartbeat, shows the fear\n" + "Ghosts appear and fade away"; - - // Create a few collections. - assertDavMkDir( davRepo, CONTEXT + "/bar" ); - assertDavMkDir( davRepo, CONTEXT + "/foo" ); - - // Create a resource - assertDavTouchFile( davRepo, CONTEXT + "/bar", "index.html", contents ); - - // Test for existance of resource - assertDavFileExists( davRepo, CONTEXT + "/bar", "index.html" ); - assertDavFileNotExists( davRepo, CONTEXT + "/foo", "index.html" ); - - // Copy resource - String actual = davRepo.getMethodDataAsString( CONTEXT + "/bar/" ); - - assertEquals( contents, actual ); - } -} diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/AbstractWebdavProviderTestCase.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/AbstractWebdavProviderTestCase.java deleted file mode 100644 index 33a210a8c..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/AbstractWebdavProviderTestCase.java +++ /dev/null @@ -1,401 +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.test; - -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpException; -import org.apache.commons.httpclient.HttpStatus; -import org.apache.commons.httpclient.methods.GetMethod; -import org.apache.commons.io.FileUtils; -import org.apache.maven.archiva.webdav.DavServerManager; -import org.apache.webdav.lib.WebdavResource; -import org.apache.webdav.lib.WebdavResources; -import org.codehaus.plexus.spring.PlexusInSpringTestCase; - -import java.io.File; -import java.io.IOException; - -/** - * AbstractWebdavProviderTestCase - * - * @author Joakim Erdfelt - * @version $Id: AbstractWebdavProviderTestCase.java 5997 2007-03-04 19:41:15Z joakime $ - */ -public abstract class AbstractWebdavProviderTestCase - extends PlexusInSpringTestCase -{ - public static final int PORT = 4321; - - public static final String CONTEXT = "/repos"; - - protected File serverRootDir = null; - - private DavServerManager manager; - - private String providerHint = "simple"; - - public DavServerManager getManager() - { - return manager; - } - - public String getProviderHint() - { - return providerHint; - } - - public void setManager( DavServerManager manager ) - { - this.manager = manager; - } - - public void setProviderHint( String providerHint ) - { - this.providerHint = providerHint; - } - - protected void setUp() - throws Exception - { - super.setUp(); - try - { - manager = (DavServerManager) lookup( DavServerManager.ROLE, getProviderHint() ); - serverRootDir = getRootDir(); - } - catch ( Exception e ) - { - tearDown(); - throw e; - } - } - - protected void tearDown() - throws Exception - { - serverRootDir = null; - - super.tearDown(); - } - - protected void dumpCollection( WebdavResource webdavResource, String path ) - throws Exception - { - webdavResource.setPath( path ); - WebdavResource resources[] = webdavResource.listWebdavResources(); - - System.out.println( "Dump Collection [" + path + "]: " + resources.length + " hits." ); - - dumpCollectionRecursive( "", webdavResource, path ); - } - - protected void dumpCollectionRecursive( String indent, WebdavResource webdavResource, String path ) - throws Exception - { - if ( indent.length() > 12 ) - { - return; - } - - WebdavResource resources[] = webdavResource.listWebdavResources(); - - for ( int i = 0; i < resources.length; i++ ) - { - System.out.println( indent + "WebDavResource[" + path + "|" + i + "]: " - + ( resources[i].isCollection() ? "(collection) " : "" ) + resources[i].getName() ); - - if ( resources[i].isCollection() ) - { - dumpCollectionRecursive( indent + " ", resources[i], path + "/" + resources[i].getName() ); - } - } - } - - // -------------------------------------------------------------------- - // Actual Test Cases. - // -------------------------------------------------------------------- - - public void assertNotExists( File basedir, String relativePath ) - { - assertNotExists( new File( basedir, relativePath ) ); - } - - public void assertNotExists( File file ) - { - if ( file.exists() ) - { - fail( "Unexpected path <" + file.getAbsolutePath() + "> should not exist." ); - } - } - - public void assertExists( File basedir, String relativePath ) - { - assertExists( new File( basedir, relativePath ) ); - } - - public void assertExists( File file ) - { - if ( !file.exists() ) - { - fail( "Expected path <" + file.getAbsolutePath() + "> does not exist." ); - } - } - - private void resetDirectory( File dir ) - { - try - { - FileUtils.deleteDirectory( dir ); - } - catch ( IOException e ) - { - fail( "Unable to delete test directory [" + dir.getAbsolutePath() + "]." ); - } - - if ( dir.exists() ) - { - fail( "Unable to execute test, test directory [" + dir.getAbsolutePath() - + "] exists, and cannot be deleted by the test case." ); - } - - if ( !dir.mkdirs() ) - { - fail( "Unable to execute test, test directory [" + dir.getAbsolutePath() + "] cannot be created." ); - } - } - - private File getRootDir() - { - if ( this.serverRootDir == null ) - { - String clazz = this.getClass().getName(); - clazz = clazz.substring( clazz.lastIndexOf( "." ) + 1 ); - serverRootDir = new File( "target/test-contents-" + clazz + "/" + getName() ); - - resetDirectory( serverRootDir ); - } - - return serverRootDir; - } - - protected File getTestDir( String subdir ) - { - File testDir = new File( getRootDir(), subdir ); - resetDirectory( testDir ); - return testDir; - } - - public boolean isHttpStatusOk( WebdavResource webdavResource ) - { - int statusCode = webdavResource.getStatusCode(); - - if ( statusCode == HttpStatus.SC_MULTI_STATUS ) - { - // TODO: find out multi-status values. - } - - return ( statusCode >= 200 ) && ( statusCode < 300 ); - } - - public void assertDavMkDir( WebdavResource webdavResource, String collectionName ) - throws Exception - { - String httpurl = webdavResource.getHttpURL().toString(); - - if ( !webdavResource.mkcolMethod( collectionName ) ) - { - fail( "Unable to create collection/dir <" + collectionName + "> against <" + httpurl + "> due to <" - + webdavResource.getStatusMessage() + ">" ); - } - - assertDavDirExists( webdavResource, collectionName ); - } - - public void assertDavFileExists( WebdavResource webdavResource, String path, String filename ) - throws Exception - { - String httpurl = webdavResource.getHttpURL().toString(); - - if ( !webdavResource.headMethod( path + "/" + filename ) ) - { - fail( "Unable to verify that file/contents <" + path + "/" + filename + "> exists against <" + httpurl - + "> due to <" + webdavResource.getStatusMessage() + ">" ); - } - - String oldPath = webdavResource.getPath(); - try - { - webdavResource.setPath( path ); - - WebdavResources resources = webdavResource.getChildResources(); - - WebdavResource testResource = resources.getResource( filename ); - - if ( testResource == null ) - { - fail( "The file/contents <" + path + "/" + filename + "> does not exist in <" + httpurl + ">" ); - } - - if ( testResource.isCollection() ) - { - fail( "The file/contents <" + path + "/" + filename - + "> is incorrectly being reported as a collection." ); - } - } - finally - { - webdavResource.setPath( oldPath ); - } - } - - public void assertDavFileNotExists( WebdavResource webdavResource, String path, String filename ) - throws Exception - { - String httpurl = webdavResource.getHttpURL().toString(); - - if ( webdavResource.headMethod( path + "/" + filename ) ) - { - fail( "Encountered unexpected file/contents <" + path + "/" + filename + "> at <" + httpurl + ">" ); - } - - String oldPath = webdavResource.getPath(); - try - { - webdavResource.setPath( path ); - - WebdavResources resources = webdavResource.getChildResources(); - - WebdavResource testResource = resources.getResource( filename ); - - if ( testResource == null ) - { - // Nothing found. we're done. - return; - } - - if ( !testResource.isCollection() ) - { - fail( "Encountered unexpected file/contents <" + path + "/" + filename + "> at <" + httpurl + ">" ); - } - } - finally - { - webdavResource.setPath( oldPath ); - } - } - - public void assertDavDirExists( WebdavResource webdavResource, String path ) - throws Exception - { - String httpurl = webdavResource.getHttpURL().toString(); - - String oldPath = webdavResource.getPath(); - try - { - webdavResource.setPath( path ); - - if ( !webdavResource.isCollection() ) - { - if ( !isHttpStatusOk( webdavResource ) ) - { - fail( "Unable to verify that path <" + path + "> is really a collection against <" + httpurl - + "> due to <" + webdavResource.getStatusMessage() + ">" ); - } - } - } - finally - { - webdavResource.setPath( oldPath ); - } - } - - public void assertDavDirNotExists( WebdavResource webdavResource, String path ) - throws Exception - { - String httpurl = webdavResource.getHttpURL().toString(); - - String oldPath = webdavResource.getPath(); - try - { - webdavResource.setPath( path ); - - if ( webdavResource.isCollection() ) - { - fail( "Encountered unexpected collection <" + path + "> at <" + httpurl + ">" ); - } - } - catch ( HttpException e ) - { - if ( e.getReasonCode() == HttpStatus.SC_NOT_FOUND ) - { - // Expected path. - return; - } - - fail( "Unable to set path due to HttpException: " + e.getReasonCode() + ":" + e.getReason() ); - } - finally - { - webdavResource.setPath( oldPath ); - } - } - - public void assertDavTouchFile( WebdavResource webdavResource, String path, String filename, String contents ) - throws Exception - { - String httpurl = webdavResource.getHttpURL().toString(); - - webdavResource.setPath( path ); - - if ( !webdavResource.putMethod( path + "/" + filename, contents ) ) - { - fail( "Unable to create file/contents <" + path + "/" + filename + "> against <" + httpurl + "> due to <" - + webdavResource.getStatusMessage() + ">" ); - } - - assertDavFileExists( webdavResource, path, filename ); - } - - protected void assertGet404( String url ) - throws IOException - { - HttpClient client = new HttpClient(); - GetMethod method = new GetMethod( url ); - - try - { - client.executeMethod( method ); - - if ( method.getStatusCode() == 404 ) - { - // Expected path. - return; - } - - fail( "Request for resource " + url + " should have resulted in an HTTP 404 (Not Found) response, " - + "instead got code " + method.getStatusCode() + " <" + method.getStatusText() + ">." ); - } - catch ( HttpException e ) - { - System.err.println( "HTTP Response: " + e.getReasonCode() + " " + e.getReason() ); - throw e; - } - } -} diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/AbstractWebdavServer.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/AbstractWebdavServer.java deleted file mode 100644 index 9c846520a..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/AbstractWebdavServer.java +++ /dev/null @@ -1,163 +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.test; - -import org.apache.maven.archiva.webdav.DavServerManager; -import org.apache.maven.archiva.webdav.servlet.basic.BasicWebDavServlet; -import org.codehaus.plexus.PlexusConstants; -import org.codehaus.plexus.PlexusContainer; -import org.codehaus.plexus.PlexusContainerException; -import org.codehaus.plexus.spring.PlexusContainerAdapter; -import org.codehaus.plexus.util.FileUtils; -import org.mortbay.jetty.Server; -import org.mortbay.jetty.servlet.Context; -import org.mortbay.jetty.servlet.ServletHandler; -import org.mortbay.jetty.servlet.ServletHolder; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; - -/** - * AbstractWebdavServer - Baseline server for starting up a BasicWebDavServlet to allow experimentation with. - * - * @author Joakim Erdfelt - * @version $Id: AbstractWebdavServer.java 5407 2007-01-12 19:41:09Z joakime $ - */ -public abstract class AbstractWebdavServer -{ - public static final int PORT = 14541; - - protected PlexusContainer container; - - protected String basedir; - - /** the jetty server */ - protected Server server; - - private DavServerManager manager; - - public String getBasedir() - { - if ( basedir != null ) - { - return basedir; - } - - basedir = System.getProperty( "basedir" ); - if ( basedir == null ) - { - basedir = new File( "" ).getAbsolutePath(); - } - - return basedir; - } - - public File getTestFile( String path ) - { - return new File( getBasedir(), path ); - } - - protected abstract String getProviderHint(); - - public void startServer() - throws Exception - { - container = createContainerInstance(); - - // ---------------------------------------------------------------------------- - // Create the DavServerManager - // ---------------------------------------------------------------------------- - - manager = (DavServerManager) container.lookup( DavServerManager.ROLE, getProviderHint() ); - - // ---------------------------------------------------------------------------- - // Create the jetty server - // ---------------------------------------------------------------------------- - - System.setProperty( "DEBUG", "" ); - System.setProperty( "org.mortbay.log.class", "org.slf4j.impl.SimpleLogger" ); - - server = new Server( PORT ); - Context root = new Context( server, "/", Context.SESSIONS ); - ServletHandler servletHandler = root.getServletHandler(); - root.setContextPath( "/" ); - root.setAttribute( PlexusConstants.PLEXUS_KEY, container ); - - // ---------------------------------------------------------------------------- - // Configure the webdav servlet - // ---------------------------------------------------------------------------- - - ServletHolder holder = servletHandler.addServletWithMapping( BasicWebDavServlet.class, "/projects/*" ); - - // Initialize server contents directory. - File serverContentsDir = new File( "target/test-server/" ); - - FileUtils.deleteDirectory( serverContentsDir ); - if ( serverContentsDir.exists() ) - { - throw new IllegalStateException( "Unable to execute test, server contents test directory [" - + serverContentsDir.getAbsolutePath() + "] exists, and cannot be deleted by the test case." ); - } - - if ( !serverContentsDir.mkdirs() ) - { - throw new IllegalStateException( "Unable to execute test, server contents test directory [" - + serverContentsDir.getAbsolutePath() + "] cannot be created." ); - } - - holder.setInitParameter( "dav.root", serverContentsDir.getAbsolutePath() ); - - // ---------------------------------------------------------------------------- - // Start the jetty server - // ---------------------------------------------------------------------------- - - server.start(); - } - - protected PlexusContainer createContainerInstance() - throws PlexusContainerException - { - return new PlexusContainerAdapter(); - } - - public void stopServer() - { - if ( server != null ) - { - try - { - server.stop(); - } - catch ( Exception e ) - { - e.printStackTrace(); - } - } - - if ( container != null ) - { - container.dispose(); - } - } -} diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/TestMultiWebDavServlet.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/TestMultiWebDavServlet.java deleted file mode 100644 index 4a8506eb0..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/test/TestMultiWebDavServlet.java +++ /dev/null @@ -1,46 +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.test; - -import org.apache.maven.archiva.webdav.DavServerException; -import org.apache.maven.archiva.webdav.servlet.multiplexed.MultiplexedWebDavServlet; - -import javax.servlet.ServletConfig; -import java.io.File; - -/** - * TestServlet - * - * @author Joakim Erdfelt - * @version $Id: TestMultiWebDavServlet.java 5407 2007-01-12 19:41:09Z joakime $ - */ -public class TestMultiWebDavServlet - extends MultiplexedWebDavServlet -{ - public void initServers( ServletConfig config ) - throws DavServerException - { - String rootSandbox = config.getInitParameter( "root.sandbox" ); - String rootSnapshots = config.getInitParameter( "root.snapshots" ); - - createServer( "sandbox", new File( rootSandbox ), config ); - createServer( "snapshots", new File( rootSnapshots ), config ); - } -} \ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/util/WrappedRepositoryRequestTest.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/util/WrappedRepositoryRequestTest.java deleted file mode 100644 index a8f4a96c3..000000000 --- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/util/WrappedRepositoryRequestTest.java +++ /dev/null @@ -1,75 +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.util; - -import org.apache.maven.archiva.webdav.TestableHttpServletRequest; -import org.codehaus.plexus.spring.PlexusInSpringTestCase; - -import javax.servlet.http.HttpServletRequest; -import java.net.MalformedURLException; - -/** - * WrappedRepositoryRequestTest - * - * @author Joakim Erdfelt - * @version $Id: WrappedRepositoryRequestTest.java 6940 2007-10-16 01:02:02Z joakime $ - */ -public class WrappedRepositoryRequestTest - extends PlexusInSpringTestCase -{ - private HttpServletRequest createHttpServletGetRequest( String url ) - throws MalformedURLException - { - TestableHttpServletRequest testrequest = new TestableHttpServletRequest(); - testrequest.setMethod( "GET" ); - testrequest.setServletPath( "/repository" ); - testrequest.setUrl( url ); - - return testrequest; - } - - public void testShort() - throws Exception - { - HttpServletRequest request = createHttpServletGetRequest( "http://machine.com/repository/org" ); - WrappedRepositoryRequest wrapreq = new WrappedRepositoryRequest( request ); - assertNotNull( wrapreq ); - - assertEquals( "/repository", wrapreq.getServletPath() ); - assertEquals( "/org", wrapreq.getPathInfo() ); - assertEquals( "/org", wrapreq.getRequestURI() ); - } - - public void testLonger() - throws Exception - { - HttpServletRequest request = createHttpServletGetRequest( "http://machine.com/repository/" - + "org/codehaus/plexus/webdav/plexus-webdav-simple/1.0-alpha-3/plexus-webdav-simple-1.0-alpha-3.jar" ); - - WrappedRepositoryRequest wrapreq = new WrappedRepositoryRequest( request ); - assertNotNull( wrapreq ); - - assertEquals( "/repository", wrapreq.getServletPath() ); - - String expected = "/org/codehaus/plexus/webdav/plexus-webdav-simple/1.0-alpha-3/plexus-webdav-simple-1.0-alpha-3.jar"; - assertEquals( expected, wrapreq.getPathInfo() ); - assertEquals( expected, wrapreq.getRequestURI() ); - } -} diff --git a/pom.xml b/pom.xml index 17f830178..97f3cd821 100644 --- a/pom.xml +++ b/pom.xml @@ -192,6 +192,11 @@ + + org.apache.jackrabbit + jackrabbit-webdav + 1.4 + javax.activation activation