1 package org.apache.archiva.webdav;
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
22 import org.apache.archiva.repository.ManagedRepositoryContent;
23 import org.apache.archiva.repository.content.StorageAsset;
24 import org.apache.archiva.webdav.util.IndexWriter;
25 import org.apache.archiva.webdav.util.MimeTypes;
26 import org.apache.jackrabbit.util.Text;
27 import org.apache.jackrabbit.webdav.DavException;
28 import org.apache.jackrabbit.webdav.DavResource;
29 import org.apache.jackrabbit.webdav.DavResourceFactory;
30 import org.apache.jackrabbit.webdav.DavResourceIterator;
31 import org.apache.jackrabbit.webdav.DavResourceLocator;
32 import org.apache.jackrabbit.webdav.DavSession;
33 import org.apache.jackrabbit.webdav.MultiStatusResponse;
34 import org.apache.jackrabbit.webdav.io.InputContext;
35 import org.apache.jackrabbit.webdav.io.OutputContext;
36 import org.apache.jackrabbit.webdav.lock.ActiveLock;
37 import org.apache.jackrabbit.webdav.lock.LockInfo;
38 import org.apache.jackrabbit.webdav.lock.LockManager;
39 import org.apache.jackrabbit.webdav.lock.Scope;
40 import org.apache.jackrabbit.webdav.lock.Type;
41 import org.apache.jackrabbit.webdav.property.DavProperty;
42 import org.apache.jackrabbit.webdav.property.DavPropertyName;
43 import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
44 import org.apache.jackrabbit.webdav.property.DavPropertySet;
45 import org.apache.jackrabbit.webdav.property.DefaultDavProperty;
46 import org.apache.jackrabbit.webdav.property.ResourceType;
47 import org.joda.time.DateTime;
48 import org.joda.time.format.DateTimeFormatter;
49 import org.joda.time.format.ISODateTimeFormat;
51 import java.io.IOException;
52 import java.nio.file.Files;
53 import java.nio.file.Path;
55 import java.util.stream.Collectors;
58 * DavResource for virtual repositories
60 public class ArchivaVirtualDavResource
61 implements DavResource
63 private static final String COMPLIANCE_CLASS = "1";
65 private ArchivaDavResourceLocator locator;
67 private DavResourceFactory factory;
69 private String logicalResource;
71 private DavPropertySet properties;
73 private boolean propsInitialized = false;
75 private static final String METHODS = "OPTIONS, GET, HEAD, POST, TRACE, PROPFIND, PROPPATCH, MKCOL";
77 private final List<StorageAsset> localResources;
79 public ArchivaVirtualDavResource(List<StorageAsset> localResources, String logicalResource, MimeTypes mimeTypes,
80 ArchivaDavResourceLocator locator, DavResourceFactory factory )
82 this.localResources = localResources;
83 this.logicalResource = logicalResource;
84 this.locator = locator;
85 this.factory = factory;
86 this.properties = new DavPropertySet();
90 public void spool( OutputContext outputContext ) {
91 if ( outputContext.hasStream() )
93 List<StorageAsset> localResourceFiles = localResources.stream().filter(Objects::nonNull)
94 .filter(repoAsset -> repoAsset.exists())
95 .sorted(Comparator.comparing(o -> o.getName())).collect(Collectors.toList());
97 IndexWriter writer = new IndexWriter(localResourceFiles, logicalResource );
98 writer.write( outputContext );
103 public void addLockManager( LockManager arg0 )
109 public void addMember( DavResource arg0, InputContext arg1 )
115 @SuppressWarnings( "unchecked" )
117 public MultiStatusResponse alterProperties( List arg0 )
123 public MultiStatusResponse alterProperties( DavPropertySet arg0, DavPropertyNameSet arg1 )
130 public void copy( DavResource arg0, boolean arg1 )
137 public boolean exists()
139 // localResources are already filtered (all files in the list are already existing)
144 public ActiveLock getLock( Type arg0, Scope arg1 )
150 public ActiveLock[] getLocks()
156 public DavResourceIterator getMembers()
162 public String getSupportedMethods()
168 public long getModificationTime()
174 public boolean hasLock( Type arg0, Scope arg1 )
180 public boolean isCollection()
186 public boolean isLockable( Type arg0, Scope arg1 )
192 public ActiveLock lock( LockInfo arg0 )
199 public void move( DavResource arg0 )
206 public ActiveLock refreshLock( LockInfo arg0, String arg1 )
213 public void removeMember( DavResource arg0 )
220 public void unlock( String arg0 )
227 public String getComplianceClass()
229 return COMPLIANCE_CLASS;
233 public DavResourceLocator getLocator()
239 public String getResourcePath()
241 return locator.getResourcePath();
245 public String getHref()
247 return locator.getHref( isCollection() );
251 public DavResourceFactory getFactory()
257 public String getDisplayName()
259 String resPath = getResourcePath();
261 return ( resPath != null ) ? Text.getName( resPath ) : resPath;
265 public DavSession getSession()
271 public DavPropertyName[] getPropertyNames()
273 return getProperties().getPropertyNames();
277 public DavProperty getProperty( DavPropertyName name )
280 return properties.get( name );
284 public DavPropertySet getProperties()
291 public void setProperty( DavProperty property )
297 public void removeProperty( DavPropertyName propertyName )
303 public DavResource getCollection()
305 DavResource parent = null;
306 if ( getResourcePath() != null && !getResourcePath().equals( "/" ) )
308 String parentPath = Text.getRelativeParent( getResourcePath(), 1 );
309 if ( parentPath.equals( "" ) )
313 DavResourceLocator parentloc =
314 locator.getFactory().createResourceLocator( locator.getPrefix(), parentPath );
317 // go back to ArchivaDavResourceFactory!
318 parent = factory.createResource( parentloc, null );
320 catch ( DavException e )
329 * Fill the set of properties
331 protected void initProperties()
333 if ( !exists() || propsInitialized )
338 // set (or reset) fundamental properties
339 if ( getDisplayName() != null )
341 properties.add( new DefaultDavProperty<>( DavPropertyName.DISPLAYNAME, getDisplayName() ) );
343 if ( isCollection() )
345 properties.add( new ResourceType( ResourceType.COLLECTION ) );
346 // Windows XP support
347 properties.add( new DefaultDavProperty<>( DavPropertyName.ISCOLLECTION, "1" ) );
351 properties.add( new ResourceType( ResourceType.DEFAULT_RESOURCE ) );
353 // Windows XP support
354 properties.add( new DefaultDavProperty<>( DavPropertyName.ISCOLLECTION, "0" ) );
357 // Need to get the ISO8601 date for properties
358 DateTime dt = new DateTime( 0 );
359 DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
360 String modifiedDate = fmt.print( dt );
362 properties.add( new DefaultDavProperty<>( DavPropertyName.GETLASTMODIFIED, modifiedDate ) );
364 properties.add( new DefaultDavProperty<>( DavPropertyName.CREATIONDATE, modifiedDate ) );
366 properties.add( new DefaultDavProperty<>( DavPropertyName.GETCONTENTLENGTH, 0 ) );
368 propsInitialized = true;
371 public String getLogicalResource()
373 return logicalResource;
376 public void setLogicalResource( String logicalResource )
378 this.logicalResource = logicalResource;