001 package railo.runtime.tag; 002 003 import java.io.File; 004 import java.io.IOException; 005 import java.util.Date; 006 007 import railo.commons.io.ModeUtil; 008 import railo.commons.io.res.Resource; 009 import railo.commons.io.res.ResourceMetaData; 010 import railo.commons.io.res.filter.AndResourceFilter; 011 import railo.commons.io.res.filter.DirectoryResourceFilter; 012 import railo.commons.io.res.filter.FileResourceFilter; 013 import railo.commons.io.res.filter.NotResourceFilter; 014 import railo.commons.io.res.filter.OrResourceFilter; 015 import railo.commons.io.res.filter.ResourceFilter; 016 import railo.commons.io.res.filter.ResourceNameFilter; 017 import railo.commons.io.res.type.file.FileResource; 018 import railo.commons.io.res.type.s3.S3; 019 import railo.commons.io.res.type.s3.S3Constants; 020 import railo.commons.io.res.type.s3.S3Exception; 021 import railo.commons.io.res.type.s3.S3Resource; 022 import railo.commons.io.res.util.ModeObjectWrap; 023 import railo.commons.io.res.util.ResourceAndResourceNameFilter; 024 import railo.commons.io.res.util.ResourceUtil; 025 import railo.commons.io.res.util.UDFFilter; 026 import railo.commons.lang.StringUtil; 027 import railo.runtime.PageContext; 028 import railo.runtime.exp.ApplicationException; 029 import railo.runtime.exp.PageException; 030 import railo.runtime.ext.tag.TagImpl; 031 import railo.runtime.functions.s3.StoreSetACL; 032 import railo.runtime.op.Caster; 033 import railo.runtime.op.Decision; 034 import railo.runtime.security.SecurityManager; 035 import railo.runtime.type.Array; 036 import railo.runtime.type.ArrayImpl; 037 import railo.runtime.type.Collection.Key; 038 import railo.runtime.type.Query; 039 import railo.runtime.type.QueryImpl; 040 import railo.runtime.type.UDF; 041 import railo.runtime.type.util.KeyConstants; 042 043 /** 044 * Handles interactions with directories. 045 * 046 * 047 * 048 **/ 049 public final class Directory extends TagImpl { 050 051 public static final int TYPE_ALL = 0; 052 public static final int TYPE_FILE = 1; 053 public static final int TYPE_DIR = 2; 054 055 public static final ResourceFilter DIRECTORY_FILTER = new DirectoryResourceFilter(); 056 public static final ResourceFilter FILE_FILTER = new FileResourceFilter(); 057 058 private static final Key MODE = KeyConstants._mode; 059 private static final Key META = KeyConstants._meta; 060 private static final Key DATE_LAST_MODIFIED = KeyConstants._dateLastModified; 061 private static final Key ATTRIBUTES = KeyConstants._attributes; 062 private static final Key DIRECTORY = KeyConstants._directory; 063 064 public static final int LIST_INFO_QUERY_ALL = 1; 065 public static final int LIST_INFO_QUERY_NAME = 2; 066 public static final int LIST_INFO_ARRAY_NAME = 4; 067 public static final int LIST_INFO_ARRAY_PATH = 8; 068 069 public static final int NAMECONFLICT_ERROR = 1; 070 // public static final int NAMECONFLICT_SKIP = 2; // FUTURE 071 public static final int NAMECONFLICT_OVERWRITE = 3; 072 // public static final int NAMECONFLICT_CLOSURE = 5; // FUTURE 073 public static final int NAMECONFLICT_UNDEFINED = NAMECONFLICT_OVERWRITE; // default 074 075 /** Optional for action = "list". Ignored by all other actions. File extension filter applied to 076 ** returned names. For example: *m. Only one mask filter can be applied at a time. */ 077 private ResourceFilter filter; 078 private ResourceAndResourceNameFilter nameFilter; 079 080 /** The name of the directory to perform the action against. */ 081 private Resource directory; 082 083 /** Defines the action to be taken with directory(ies) specified in directory. */ 084 private String action="list"; 085 086 /** Optional for action = "list". Ignored by all other actions. The query columns by which to sort 087 ** the directory listing. Any combination of columns from query output can be specified in comma-separated list. 088 ** You can specify ASC (ascending) or DESC (descending) as qualifiers for column names. ASC is the default */ 089 private String sort; 090 091 /** Used with action = "Create" to define the permissions for a directory on UNIX and Linux 092 ** platforms. Ignored on Windows. Options correspond to the octal values of the UNIX chmod command. From 093 ** left to right, permissions are assigned for owner, group, and other. */ 094 private int mode=-1; 095 096 /** Required for action = "rename". Ignored by all other actions. The new name of the directory 097 ** specified in the directory attribute. */ 098 private String strNewdirectory; 099 100 /** Required for action = "list". Ignored by all other actions. Name of output query for directory 101 ** listing. */ 102 private String name=null; 103 104 105 private boolean recurse=false; 106 107 private String serverPassword; 108 109 private int type=TYPE_ALL; 110 //private boolean listOnlyNames; 111 private int listInfo=LIST_INFO_QUERY_ALL; 112 //private int acl=S3Constants.ACL_UNKNOW; 113 private Object acl=null; 114 private int storage=S3Constants.STORAGE_UNKNOW; 115 private String destination; 116 117 private int nameconflict = NAMECONFLICT_UNDEFINED; 118 119 120 @Override 121 public void release() { 122 super.release(); 123 acl=null; 124 storage=S3Constants.STORAGE_UNKNOW; 125 126 127 type=TYPE_ALL; 128 filter=null; 129 nameFilter=null; 130 destination=null; 131 directory=null; 132 action="list"; 133 sort=null; 134 mode=-1; 135 strNewdirectory=null; 136 name=null; 137 recurse=false; 138 serverPassword=null; 139 listInfo=LIST_INFO_QUERY_ALL; 140 141 nameconflict = NAMECONFLICT_UNDEFINED; 142 } 143 144 145 146 /** 147 * sets a filter 148 * @param pattern 149 * @throws PageException 150 **/ 151 152 153 154 155 156 157 158 public void setFilter(Object filter) throws PageException { 159 this.filter=nameFilter=UDFFilter.createResourceAndResourceNameFilter(filter); 160 } 161 162 public void setFilter(UDF filter) throws PageException { 163 this.filter=nameFilter=UDFFilter.createResourceAndResourceNameFilter(filter); 164 } 165 166 public void setFilter(String pattern) { 167 168 this.filter = nameFilter = UDFFilter.createResourceAndResourceNameFilter( pattern ); 169 } 170 171 /** set the value acl 172 * used only for s3 resources, for all others ignored 173 * @param charset value to set 174 * @throws ApplicationException 175 * @Deprecated only exists for backward compatibility to old ra files. 176 **/ 177 public void setAcl(String acl) throws ApplicationException { 178 this.acl=acl; 179 /*acl=acl.trim().toLowerCase(); 180 181 if("private".equals(acl)) this.acl=S3Constants.ACL_PRIVATE; 182 else if("public-read".equals(acl)) this.acl=S3Constants.ACL_PRIVATE; 183 else if("public-read-write".equals(acl)) this.acl=S3Constants.ACL_PUBLIC_READ_WRITE; 184 else if("authenticated-read".equals(acl)) this.acl=S3Constants.ACL_AUTH_READ; 185 186 else throw new ApplicationException("invalid value for attribute acl ["+acl+"]", 187 "valid values are [private,public-read,public-read-write,authenticated-read]");*/ 188 } 189 190 public void setAcl(Object acl) { 191 this.acl=acl; 192 } 193 194 public void setStoreacl(Object acl) { 195 this.acl=acl; 196 } 197 198 /** set the value storage 199 * used only for s3 resources, for all others ignored 200 * @param charset value to set 201 * @throws PageException 202 **/ 203 public void setStorage(String storage) throws PageException { 204 try { 205 this.storage=S3.toIntStorage(storage); 206 } catch (S3Exception e) { 207 throw Caster.toPageException(e); 208 } 209 } 210 public void setStorelocation(String storage) throws PageException { 211 setStorage(storage); 212 } 213 214 215 216 public void setServerpassword(String serverPassword) { 217 this.serverPassword=serverPassword; 218 } 219 220 221 public void setListinfo(String strListinfo) { 222 strListinfo=strListinfo.trim().toLowerCase(); 223 this.listInfo="name".equals(strListinfo)?LIST_INFO_QUERY_NAME:LIST_INFO_QUERY_ALL; 224 } 225 226 227 228 /** set the value directory 229 * The name of the directory to perform the action against. 230 * @param directory value to set 231 **/ 232 public void setDirectory(String directory) { 233 234 this.directory=ResourceUtil.toResourceNotExisting(pageContext ,directory); 235 //print.ln(this.directory); 236 } 237 238 /** set the value action 239 * Defines the action to be taken with directory(ies) specified in directory. 240 * @param action value to set 241 **/ 242 public void setAction(String action) { 243 this.action=action.toLowerCase(); 244 } 245 246 /** set the value sort 247 * Optional for action = "list". Ignored by all other actions. The query columns by which to sort 248 * the directory listing. Any combination of columns from query output can be specified in comma-separated list. 249 * You can specify ASC (ascending) or DESC (descending) as qualifiers for column names. ASC is the default 250 * @param sort value to set 251 **/ 252 public void setSort(String sort) { 253 if(sort.trim().length()>0) 254 this.sort=sort; 255 } 256 257 /** set the value mode 258 * Used with action = "Create" to define the permissions for a directory on UNIX and Linux 259 * platforms. Ignored on Windows. Options correspond to the octal values of the UNIX chmod command. From 260 * left to right, permissions are assigned for owner, group, and other. 261 * @param mode value to set 262 * @throws PageException 263 **/ 264 public void setMode(String mode) throws PageException { 265 try { 266 this.mode=ModeUtil.toOctalMode(mode); 267 } 268 catch (IOException e) { 269 throw Caster.toPageException(e); 270 } 271 } 272 273 /** set the value newdirectory 274 * Required for action = "rename". Ignored by all other actions. The new name of the directory 275 * specified in the directory attribute. 276 * @param newdirectory value to set 277 **/ 278 public void setNewdirectory(String newdirectory) { 279 //this.newdirectory=ResourceUtil.toResourceNotExisting(pageContext ,newdirectory); 280 this.strNewdirectory=newdirectory; 281 } 282 public void setDestination(String destination) { 283 this.destination=destination; 284 } 285 286 /** set the value name 287 * Required for action = "list". Ignored by all other actions. Name of output query for directory 288 * listing. 289 * @param name value to set 290 **/ 291 public void setName(String name) { 292 this.name=name; 293 } 294 295 /** 296 * @param recurse The recurse to set. 297 */ 298 public void setRecurse(boolean recurse) { 299 this.recurse = recurse; 300 } 301 302 /** set the value nameconflict 303 * Action to take if destination directory is the same as that of a file in the directory. 304 * @param nameconflict value to set 305 * @throws ApplicationException 306 **/ 307 public void setNameconflict(String nameconflict) throws ApplicationException { 308 this.nameconflict = toNameconflict( nameconflict ); 309 } 310 311 public static int toNameconflict( String nameconflict ) throws ApplicationException { 312 313 if ( StringUtil.isEmpty( nameconflict, true ) ) 314 return NAMECONFLICT_UNDEFINED; 315 316 nameconflict = nameconflict.trim(); 317 318 if ( "merge".equalsIgnoreCase( nameconflict ) || "overwrite".equalsIgnoreCase( nameconflict ) ) 319 return NAMECONFLICT_OVERWRITE; 320 321 if ( "error".equalsIgnoreCase( nameconflict ) ) 322 return NAMECONFLICT_ERROR; 323 324 throw new ApplicationException("invalid value for attribute/argument nameconflict ["+nameconflict+"]", 325 "valid values are [error,merge,overwrite]"); 326 } 327 328 329 @Override 330 public int doStartTag() throws PageException { 331 332 //securityManager = pageContext.getConfig().getSecurityManager(); 333 if(action.equals("list")) { 334 Object res=actionList(pageContext,directory,serverPassword,type,filter,nameFilter,listInfo,recurse,sort); 335 if(!StringUtil.isEmpty(name) && res!=null)pageContext.setVariable(name,res); 336 } 337 else if(action.equals("create")) actionCreate(pageContext,directory,serverPassword,true,mode,acl,storage); 338 else if(action.equals("delete")) actionDelete(pageContext,directory,recurse,serverPassword); 339 else if(action.equals("forcedelete")) actionDelete(pageContext,directory,true,serverPassword); 340 else if(action.equals("rename")) actionRename(pageContext,directory,strNewdirectory,serverPassword,acl,storage); 341 else if(action.equals("copy")) { 342 if(StringUtil.isEmpty(destination,true) && !StringUtil.isEmpty(strNewdirectory,true)) { 343 destination=strNewdirectory.trim(); 344 } 345 actionCopy(pageContext,directory,destination,serverPassword,acl,storage,filter,recurse, nameconflict); 346 } 347 else throw new ApplicationException("invalid action ["+action+"] for the tag directory"); 348 349 return SKIP_BODY; 350 } 351 352 353 @Override 354 public int doEndTag() { 355 return EVAL_PAGE; 356 } 357 358 /** 359 * list all files and directories inside a directory 360 * @throws PageException 361 */ 362 public static Object actionList(PageContext pageContext,Resource directory, String serverPassword, int type,ResourceFilter filter,ResourceAndResourceNameFilter nameFilter, 363 int listInfo,boolean recurse,String sort) throws PageException { 364 // check directory 365 SecurityManager securityManager = pageContext.getConfig().getSecurityManager(); 366 securityManager.checkFileLocation(pageContext.getConfig(),directory,serverPassword); 367 368 if(type!=TYPE_ALL) { 369 ResourceFilter typeFilter = (type==TYPE_DIR)?DIRECTORY_FILTER:FILE_FILTER; 370 if(filter==null) filter=typeFilter; 371 else filter=new AndResourceFilter(new ResourceFilter[]{typeFilter,filter}); 372 } 373 374 375 // create query Object 376 String[] names = new String[]{"name","size","type","dateLastModified","attributes","mode","directory"}; 377 String[] types=new String[]{"VARCHAR","DOUBLE","VARCHAR","DATE","VARCHAR","VARCHAR","VARCHAR"}; 378 379 boolean hasMeta=directory instanceof ResourceMetaData; 380 if(hasMeta){ 381 names = new String[]{"name","size","type","dateLastModified","attributes","mode","directory","meta"}; 382 types=new String[]{"VARCHAR","DOUBLE","VARCHAR","DATE","VARCHAR","VARCHAR","VARCHAR","OBJECT"}; 383 } 384 Array array=null; 385 Query query=null; 386 Object rtn; 387 if(listInfo==LIST_INFO_QUERY_ALL || listInfo==LIST_INFO_QUERY_NAME){ 388 boolean listOnlyNames=listInfo==LIST_INFO_QUERY_NAME; 389 rtn=query=new QueryImpl( 390 listOnlyNames?new String[]{"name"}:names, 391 listOnlyNames?new String[]{"VARCHAR"}:types, 392 0,"query"); 393 } 394 else 395 rtn=array=new ArrayImpl(); 396 397 if(!directory.exists()){ 398 if(directory instanceof FileResource) return rtn; 399 throw new ApplicationException("directory ["+directory.toString()+"] doesn't exist"); 400 } 401 if(!directory.isDirectory()){ 402 if(directory instanceof FileResource) return rtn; 403 throw new ApplicationException("file ["+directory.toString()+"] exists, but isn't a directory"); 404 } 405 if(!directory.isReadable()){ 406 if(directory instanceof FileResource) return rtn; 407 throw new ApplicationException("no access to read directory ["+directory.toString()+"]"); 408 } 409 410 long startNS=System.nanoTime(); 411 412 try { 413 // Query All 414 if(listInfo==LIST_INFO_QUERY_ALL) 415 _fillQueryAll(query,directory,filter,0,hasMeta,recurse); 416 417 // Query Name 418 else if(listInfo==LIST_INFO_QUERY_NAME) { 419 if(recurse || type!=TYPE_ALL)_fillQueryNamesRec("",query, directory, filter, 0,recurse); 420 else _fillQueryNames(query, directory, nameFilter, 0); 421 } 422 423 //Array Name/Path 424 else if(listInfo==LIST_INFO_ARRAY_NAME || listInfo==LIST_INFO_ARRAY_PATH) { 425 boolean onlyName=listInfo==LIST_INFO_ARRAY_NAME; 426 if(!onlyName || recurse || type!=TYPE_ALL)_fillArrayPathOrName(array, directory, nameFilter, 0, recurse, onlyName);//QueryNamesRec("",query, directory, filter, 0,recurse); 427 else _fillArrayName(array, directory, nameFilter, 0); 428 } 429 430 431 } catch (IOException e) { 432 throw Caster.toPageException(e); 433 } 434 435 // sort 436 if(sort!=null && query!=null) { 437 String[] arr=sort.toLowerCase().split(","); 438 for(int i=arr.length-1;i>=0;i--) { 439 try { 440 String[] col=arr[i].trim().split("\\s+"); 441 if(col.length==1)query.sort(col[0].trim()); 442 else if(col.length==2) { 443 String order=col[1].toLowerCase().trim(); 444 if(order.equals("asc")) 445 query.sort(col[0],railo.runtime.type.Query.ORDER_ASC); 446 else if(order.equals("desc")) 447 query.sort(col[0],railo.runtime.type.Query.ORDER_DESC); 448 else 449 throw new ApplicationException("invalid order type ["+col[1]+"]"); 450 } 451 } 452 catch(Throwable t) {} 453 } 454 } 455 if(query!=null)query.setExecutionTime(System.nanoTime()-startNS); 456 return rtn; 457 } 458 459 460 461 462 private static int _fillQueryAll(Query query, Resource directory, ResourceFilter filter, int count, boolean hasMeta, boolean recurse) throws PageException, IOException { 463 //long start=System.currentTimeMillis(); 464 Resource[] list=directory.listResources(); 465 466 if(list==null || list.length==0) return count; 467 String dir=directory.getCanonicalPath(); 468 // fill data to query 469 //query.addRow(list.length); 470 boolean isDir; 471 for(int i=0;i<list.length;i++) { 472 if(filter==null || filter.accept(list[i])) { 473 query.addRow(1); 474 count++; 475 query.setAt(KeyConstants._name,count,list[i].getName()); 476 isDir=list[i].isDirectory(); 477 query.setAt(KeyConstants._size,count,new Double(isDir?0:list[i].length())); 478 query.setAt(KeyConstants._type,count,isDir?"Dir":"File"); 479 if(directory.getResourceProvider().isModeSupported()){ 480 481 query.setAt(MODE,count,new ModeObjectWrap(list[i])); 482 } 483 query.setAt(DATE_LAST_MODIFIED,count,new Date(list[i].lastModified())); 484 query.setAt(ATTRIBUTES,count,getFileAttribute(list[i],true)); 485 486 if(hasMeta){ 487 query.setAt(META,count,((ResourceMetaData)list[i]).getMetaData()); 488 } 489 490 query.setAt(DIRECTORY,count,dir); 491 } 492 if(recurse && list[i].isDirectory()) 493 count=_fillQueryAll(query,list[i],filter,count,hasMeta,recurse); 494 } 495 return count; 496 } 497 // this method only exists for performance reasion 498 private static int _fillQueryNames(Query query, Resource directory, ResourceNameFilter filter, int count) throws PageException { 499 String[] list=directory.list(); 500 if(list==null || list.length==0) return count; 501 for(int i=0;i<list.length;i++) { 502 if(filter==null || filter.accept(directory,list[i])) { 503 query.addRow(1); 504 count++; 505 query.setAt(KeyConstants._name,count,list[i]); 506 } 507 } 508 return count; 509 } 510 511 private static int _fillQueryNamesRec(String parent, Query query, Resource directory, ResourceFilter filter, int count, boolean recurse) throws PageException { 512 Resource[] list=directory.listResources(); 513 if(list==null || list.length==0) return count; 514 for(int i=0;i<list.length;i++) { 515 if(filter==null || filter.accept(list[i])) { 516 query.addRow(1); 517 count++; 518 query.setAt(KeyConstants._name,count,parent.concat(list[i].getName())); 519 520 } 521 if(recurse && list[i].isDirectory()) 522 count=_fillQueryNamesRec(parent+list[i].getName()+"/",query,list[i],filter,count,recurse); 523 } 524 return count; 525 } 526 527 private static int _fillArrayPathOrName(Array arr, Resource directory, ResourceFilter filter, int count, boolean recurse,boolean onlyName) throws PageException { 528 Resource[] list=directory.listResources(); 529 if(list==null || list.length==0) return count; 530 for(int i=0;i<list.length;i++) { 531 if(filter==null || filter.accept(list[i])) { 532 arr.appendEL(onlyName?list[i].getName():list[i].getAbsolutePath()); 533 count++; 534 535 } 536 if(recurse && list[i].isDirectory()) 537 count=_fillArrayPathOrName(arr,list[i],filter,count,recurse,onlyName); 538 } 539 return count; 540 } 541 542 // this method only exists for performance reasion 543 private static int _fillArrayName(Array arr, Resource directory, ResourceNameFilter filter, int count) { 544 String[] list=directory.list(); 545 if(list==null || list.length==0) return count; 546 for(int i=0;i<list.length;i++) { 547 if(filter==null || filter.accept(directory,list[i])) { 548 arr.appendEL(list[i]); 549 } 550 } 551 return count; 552 } 553 554 555 556 /** 557 * create a directory 558 * @throws PageException 559 */ 560 public static void actionCreate(PageContext pc,Resource directory,String serverPassword, boolean doParent,int mode,Object acl,int storage) throws PageException { 561 562 SecurityManager securityManager = pc.getConfig().getSecurityManager(); 563 securityManager.checkFileLocation(pc.getConfig(),directory,serverPassword); 564 565 if(directory.exists()) { 566 if(directory.isDirectory()) 567 throw new ApplicationException("directory ["+directory.toString()+"] already exist"); 568 else if(directory.isFile()) 569 throw new ApplicationException("can't create directory ["+directory.toString()+"], it exist a file with same name"); 570 } 571 //if(!directory.mkdirs()) throw new ApplicationException("can't create directory ["+directory.toString()+"]"); 572 try { 573 directory.createDirectory(doParent); 574 } catch (IOException ioe) { 575 throw Caster.toPageException(ioe); 576 } 577 578 // set S3 stuff 579 setS3Attrs(directory,acl,storage); 580 581 // Set Mode 582 if(mode!=-1) { 583 try { 584 directory.setMode(mode); 585 //FileUtil.setMode(directory,mode); 586 } catch (IOException e) { 587 throw Caster.toPageException(e); 588 } 589 } 590 } 591 592 private static void setS3Attrs(Resource res,Object acl,int storage) throws PageException { 593 String scheme = res.getResourceProvider().getScheme(); 594 595 if("s3".equalsIgnoreCase(scheme)){ 596 S3Resource s3r=(S3Resource) res; 597 if(acl!=null){ 598 try { 599 // old way 600 if(Decision.isString(acl)) { 601 if(Decision.isInteger(acl)) s3r.setACL(Caster.toIntValue(acl)); 602 else s3r.setACL(S3.toIntACL(Caster.toString(acl))); 603 } 604 // new way 605 else { 606 StoreSetACL.invoke(s3r, acl); 607 } 608 } catch (IOException e) { 609 throw Caster.toPageException(e); 610 } 611 } 612 613 if(storage!=S3Constants.STORAGE_UNKNOW) s3r.setStorage(storage); 614 } 615 } 616 617 618 619 /** 620 * delete directory 621 * @param dir 622 * @param forceDelete 623 * @throws PageException 624 */ 625 public static void actionDelete(PageContext pc,Resource dir, boolean forceDelete,String serverPassword) throws PageException { 626 SecurityManager securityManager = pc.getConfig().getSecurityManager(); 627 securityManager.checkFileLocation(pc.getConfig(),dir,serverPassword); 628 629 // directory doesn't exist 630 if(!dir.exists()) { 631 if(dir.isDirectory()) 632 throw new ApplicationException("directory ["+dir.toString()+"] doesn't exist"); 633 else if(dir.isFile()) 634 throw new ApplicationException("file ["+dir.toString()+"] doesn't exist and isn't a directory"); 635 } 636 637 // check if file 638 if(dir.isFile()) 639 throw new ApplicationException("can't delete ["+dir.toString()+"], it isn't a directory it is a file"); 640 641 // delete directory 642 try { 643 dir.remove(forceDelete); 644 } catch (IOException e) { 645 throw Caster.toPageException(e); 646 } 647 } 648 649 /** 650 * rename a directory to a new Name 651 * @throws PageException 652 */ 653 public static void actionRename(PageContext pc,Resource directory,String strNewdirectory,String serverPassword, Object acl,int storage) throws PageException { 654 // check directory 655 SecurityManager securityManager = pc.getConfig().getSecurityManager(); 656 securityManager.checkFileLocation(pc.getConfig(),directory,serverPassword); 657 658 659 if(!directory.exists()) 660 throw new ApplicationException("the directory ["+directory.toString()+"] doesn't exist"); 661 if(!directory.isDirectory()) 662 throw new ApplicationException("the file ["+directory.toString()+"] exists, but it isn't a directory"); 663 if(!directory.canRead()) 664 throw new ApplicationException("no access to read directory ["+directory.toString()+"]"); 665 666 if(strNewdirectory==null) 667 throw new ApplicationException("the attribute [newDirectory] is not defined"); 668 669 // real to source 670 Resource newdirectory=toDestination(pc,strNewdirectory,directory); 671 672 securityManager.checkFileLocation(pc.getConfig(),newdirectory,serverPassword); 673 if(newdirectory.exists()) 674 throw new ApplicationException("new directory ["+newdirectory.toString()+"] already exists"); 675 try { 676 directory.moveTo(newdirectory); 677 } 678 catch(Throwable t) { 679 throw Caster.toPageException(t); 680 } 681 682 // set S3 stuff 683 setS3Attrs(directory,acl,storage); 684 685 } 686 687 688 public static void actionCopy(PageContext pc,Resource directory,String strDestination,String serverPassword, Object acl,int storage, ResourceFilter filter, boolean recurse, int nameconflict) throws PageException { 689 // check directory 690 SecurityManager securityManager = pc.getConfig().getSecurityManager(); 691 securityManager.checkFileLocation(pc.getConfig(),directory,serverPassword); 692 693 694 if(!directory.exists()) 695 throw new ApplicationException("directory ["+directory.toString()+"] doesn't exist"); 696 if(!directory.isDirectory()) 697 throw new ApplicationException("file ["+directory.toString()+"] exists, but isn't a directory"); 698 if(!directory.canRead()) 699 throw new ApplicationException("no access to read directory ["+directory.toString()+"]"); 700 701 if(StringUtil.isEmpty(strDestination)) 702 throw new ApplicationException("attribute destination is not defined"); 703 704 // real to source 705 Resource newdirectory=toDestination(pc,strDestination,directory); 706 707 if ( nameconflict == NAMECONFLICT_ERROR && newdirectory.exists() ) 708 throw new ApplicationException("new directory ["+newdirectory.toString()+"] already exist"); 709 710 securityManager.checkFileLocation(pc.getConfig(),newdirectory,serverPassword); 711 712 try { 713 // has already a filter 714 if(filter!=null) { 715 if(recurse) filter=new OrResourceFilter(new ResourceFilter[]{ 716 filter,DirectoryResourceFilter.FILTER 717 }); 718 } 719 else { 720 if(!recurse)filter=new NotResourceFilter(DirectoryResourceFilter.FILTER); 721 } 722 ResourceUtil.copyRecursive(directory, newdirectory,filter); 723 } 724 catch(Throwable t) { 725 throw new ApplicationException(t.getMessage()); 726 } 727 728 // set S3 stuff 729 setS3Attrs(directory,acl,storage); 730 731 } 732 733 734 private static Resource toDestination(PageContext pageContext,String path, Resource source) { 735 if(source!=null && path.indexOf(File.separatorChar)==-1 && path.indexOf('/')==-1 && path.indexOf('\\')==-1) { 736 Resource p = source.getParentResource(); 737 if(p!=null)return p.getRealResource(path); 738 } 739 return ResourceUtil.toResourceNotExisting(pageContext ,path); 740 } 741 742 743 744 private static String getFileAttribute(Resource file, boolean exists){ 745 return exists && !file.isWriteable() ? "R".concat(file.isHidden() ? "H" : "") : file.isHidden() ? "H" : ""; 746 } 747 748 749 750 /** 751 * @param type the type to set 752 */ 753 public void setType(String strType) throws ApplicationException { 754 strType=strType.trim().toLowerCase(); 755 756 757 if("all".equals(strType)) type=TYPE_ALL; 758 else if("dir".equals(strType)) type=TYPE_DIR; 759 else if("directory".equals(strType)) type=TYPE_DIR; 760 else if("file".equals(strType)) type=TYPE_FILE; 761 else throw new ApplicationException("invalid type ["+strType+"] for the tag directory"); 762 763 } 764 765 766 767 }