001package org.apache.archiva.webdav; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import org.apache.jackrabbit.util.Text; 023import org.apache.jackrabbit.webdav.DavException; 024import org.apache.jackrabbit.webdav.DavResource; 025import org.apache.jackrabbit.webdav.DavResourceFactory; 026import org.apache.jackrabbit.webdav.DavResourceIterator; 027import org.apache.jackrabbit.webdav.DavResourceLocator; 028import org.apache.jackrabbit.webdav.DavSession; 029import org.apache.jackrabbit.webdav.MultiStatusResponse; 030import org.apache.jackrabbit.webdav.io.InputContext; 031import org.apache.jackrabbit.webdav.io.OutputContext; 032import org.apache.jackrabbit.webdav.lock.ActiveLock; 033import org.apache.jackrabbit.webdav.lock.LockInfo; 034import org.apache.jackrabbit.webdav.lock.LockManager; 035import org.apache.jackrabbit.webdav.lock.Scope; 036import org.apache.jackrabbit.webdav.lock.Type; 037import org.apache.jackrabbit.webdav.property.DavProperty; 038import org.apache.jackrabbit.webdav.property.DavPropertyName; 039import org.apache.jackrabbit.webdav.property.DavPropertyNameSet; 040import org.apache.jackrabbit.webdav.property.DavPropertySet; 041import org.apache.jackrabbit.webdav.property.DefaultDavProperty; 042import org.apache.jackrabbit.webdav.property.ResourceType; 043import org.apache.archiva.webdav.util.IndexWriter; 044import org.apache.archiva.webdav.util.MimeTypes; 045import org.joda.time.DateTime; 046import org.joda.time.format.DateTimeFormatter; 047import org.joda.time.format.ISODateTimeFormat; 048 049import java.io.File; 050import java.io.IOException; 051import java.util.ArrayList; 052import java.util.Collections; 053import java.util.List; 054 055/** 056 * DavResource for virtual repositories 057 */ 058public class ArchivaVirtualDavResource 059 implements DavResource 060{ 061 private static final String COMPLIANCE_CLASS = "1"; 062 063 private ArchivaDavResourceLocator locator; 064 065 private DavResourceFactory factory; 066 067 private String logicalResource; 068 069 private DavPropertySet properties; 070 071 private boolean propsInitialized = false; 072 073 private static final String METHODS = "OPTIONS, GET, HEAD, POST, TRACE, PROPFIND, PROPPATCH, MKCOL"; 074 075 private final List<File> localResources; 076 077 public ArchivaVirtualDavResource( List<File> localResources, String logicalResource, MimeTypes mimeTypes, 078 ArchivaDavResourceLocator locator, DavResourceFactory factory ) 079 { 080 this.localResources = localResources; 081 this.logicalResource = logicalResource; 082 this.locator = locator; 083 this.factory = factory; 084 this.properties = new DavPropertySet(); 085 } 086 087 @Override 088 public void spool( OutputContext outputContext ) 089 throws IOException 090 { 091 if ( outputContext.hasStream() ) 092 { 093 Collections.sort( localResources ); 094 List<File> localResourceFiles = new ArrayList<>(); 095 096 for ( File resourceFile : localResources ) 097 { 098 if ( resourceFile.exists() ) 099 { 100 localResourceFiles.add( resourceFile ); 101 } 102 } 103 104 IndexWriter writer = new IndexWriter( this, localResourceFiles, logicalResource ); 105 writer.write( outputContext ); 106 } 107 } 108 109 @Override 110 public void addLockManager( LockManager arg0 ) 111 { 112 113 } 114 115 @Override 116 public void addMember( DavResource arg0, InputContext arg1 ) 117 throws DavException 118 { 119 120 } 121 122 @SuppressWarnings( "unchecked" ) 123 @Override 124 public MultiStatusResponse alterProperties( List arg0 ) 125 throws DavException 126 { 127 return null; 128 } 129 130 public MultiStatusResponse alterProperties( DavPropertySet arg0, DavPropertyNameSet arg1 ) 131 throws DavException 132 { 133 return null; 134 } 135 136 @Override 137 public void copy( DavResource arg0, boolean arg1 ) 138 throws DavException 139 { 140 141 } 142 143 @Override 144 public boolean exists() 145 { 146 // localResources are already filtered (all files in the list are already existing) 147 return true; 148 } 149 150 @Override 151 public ActiveLock getLock( Type arg0, Scope arg1 ) 152 { 153 return null; 154 } 155 156 @Override 157 public ActiveLock[] getLocks() 158 { 159 return null; 160 } 161 162 @Override 163 public DavResourceIterator getMembers() 164 { 165 return null; 166 } 167 168 @Override 169 public String getSupportedMethods() 170 { 171 return METHODS; 172 } 173 174 @Override 175 public long getModificationTime() 176 { 177 return 0; 178 } 179 180 @Override 181 public boolean hasLock( Type arg0, Scope arg1 ) 182 { 183 return false; 184 } 185 186 @Override 187 public boolean isCollection() 188 { 189 return true; 190 } 191 192 @Override 193 public boolean isLockable( Type arg0, Scope arg1 ) 194 { 195 return false; 196 } 197 198 @Override 199 public ActiveLock lock( LockInfo arg0 ) 200 throws DavException 201 { 202 return null; 203 } 204 205 @Override 206 public void move( DavResource arg0 ) 207 throws DavException 208 { 209 210 } 211 212 @Override 213 public ActiveLock refreshLock( LockInfo arg0, String arg1 ) 214 throws DavException 215 { 216 return null; 217 } 218 219 @Override 220 public void removeMember( DavResource arg0 ) 221 throws DavException 222 { 223 224 } 225 226 @Override 227 public void unlock( String arg0 ) 228 throws DavException 229 { 230 231 } 232 233 @Override 234 public String getComplianceClass() 235 { 236 return COMPLIANCE_CLASS; 237 } 238 239 @Override 240 public DavResourceLocator getLocator() 241 { 242 return locator; 243 } 244 245 @Override 246 public String getResourcePath() 247 { 248 return locator.getResourcePath(); 249 } 250 251 @Override 252 public String getHref() 253 { 254 return locator.getHref( isCollection() ); 255 } 256 257 @Override 258 public DavResourceFactory getFactory() 259 { 260 return factory; 261 } 262 263 @Override 264 public String getDisplayName() 265 { 266 String resPath = getResourcePath(); 267 268 return ( resPath != null ) ? Text.getName( resPath ) : resPath; 269 } 270 271 @Override 272 public DavSession getSession() 273 { 274 return null; 275 } 276 277 @Override 278 public DavPropertyName[] getPropertyNames() 279 { 280 return getProperties().getPropertyNames(); 281 } 282 283 @Override 284 public DavProperty getProperty( DavPropertyName name ) 285 { 286 initProperties(); 287 return properties.get( name ); 288 } 289 290 @Override 291 public DavPropertySet getProperties() 292 { 293 initProperties(); 294 return properties; 295 } 296 297 @Override 298 public void setProperty( DavProperty property ) 299 throws DavException 300 { 301 } 302 303 @Override 304 public void removeProperty( DavPropertyName propertyName ) 305 throws DavException 306 { 307 } 308 309 @Override 310 public DavResource getCollection() 311 { 312 DavResource parent = null; 313 if ( getResourcePath() != null && !getResourcePath().equals( "/" ) ) 314 { 315 String parentPath = Text.getRelativeParent( getResourcePath(), 1 ); 316 if ( parentPath.equals( "" ) ) 317 { 318 parentPath = "/"; 319 } 320 DavResourceLocator parentloc = 321 locator.getFactory().createResourceLocator( locator.getPrefix(), parentPath ); 322 try 323 { 324 // go back to ArchivaDavResourceFactory! 325 parent = factory.createResource( parentloc, null ); 326 } 327 catch ( DavException e ) 328 { 329 // should not occur 330 } 331 } 332 return parent; 333 } 334 335 /** 336 * Fill the set of properties 337 */ 338 protected void initProperties() 339 { 340 if ( !exists() || propsInitialized ) 341 { 342 return; 343 } 344 345 // set (or reset) fundamental properties 346 if ( getDisplayName() != null ) 347 { 348 properties.add( new DefaultDavProperty( DavPropertyName.DISPLAYNAME, getDisplayName() ) ); 349 } 350 if ( isCollection() ) 351 { 352 properties.add( new ResourceType( ResourceType.COLLECTION ) ); 353 // Windows XP support 354 properties.add( new DefaultDavProperty( DavPropertyName.ISCOLLECTION, "1" ) ); 355 } 356 else 357 { 358 properties.add( new ResourceType( ResourceType.DEFAULT_RESOURCE ) ); 359 360 // Windows XP support 361 properties.add( new DefaultDavProperty( DavPropertyName.ISCOLLECTION, "0" ) ); 362 } 363 364 // Need to get the ISO8601 date for properties 365 DateTime dt = new DateTime( 0 ); 366 DateTimeFormatter fmt = ISODateTimeFormat.dateTime(); 367 String modifiedDate = fmt.print( dt ); 368 369 properties.add( new DefaultDavProperty( DavPropertyName.GETLASTMODIFIED, modifiedDate ) ); 370 371 properties.add( new DefaultDavProperty( DavPropertyName.CREATIONDATE, modifiedDate ) ); 372 373 properties.add( new DefaultDavProperty( DavPropertyName.GETCONTENTLENGTH, 0 ) ); 374 375 propsInitialized = true; 376 } 377 378 public String getLogicalResource() 379 { 380 return logicalResource; 381 } 382 383 public void setLogicalResource( String logicalResource ) 384 { 385 this.logicalResource = logicalResource; 386 } 387}