package railo.runtime.tag;
import static railo.runtime.tag.util.FileUtil.NAMECONFLICT_ERROR;
import static railo.runtime.tag.util.FileUtil.NAMECONFLICT_OVERWRITE;
import static railo.runtime.tag.util.FileUtil.NAMECONFLICT_SKIP;
import static railo.runtime.tag.util.FileUtil.NAMECONFLICT_UNDEFINED;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import railo.commons.io.ModeUtil;
import railo.commons.io.res.Resource;
import railo.commons.io.res.ResourceMetaData;
import railo.commons.io.res.filter.AndResourceFilter;
import railo.commons.io.res.filter.DirectoryResourceFilter;
import railo.commons.io.res.filter.FileResourceFilter;
import railo.commons.io.res.filter.NotResourceFilter;
import railo.commons.io.res.filter.OrResourceFilter;
import railo.commons.io.res.filter.ResourceFilter;
import railo.commons.io.res.filter.ResourceNameFilter;
import railo.commons.io.res.type.file.FileResource;
import railo.commons.io.res.type.s3.S3;
import railo.commons.io.res.type.s3.S3Constants;
import railo.commons.io.res.type.s3.S3Exception;
import railo.commons.io.res.type.s3.S3Resource;
import railo.commons.io.res.util.ModeObjectWrap;
import railo.commons.io.res.util.ResourceAndResourceNameFilter;
import railo.commons.io.res.util.ResourceUtil;
import railo.commons.io.res.util.UDFFilter;
import railo.commons.lang.StringUtil;
import railo.runtime.PageContext;
import railo.runtime.exp.ApplicationException;
import railo.runtime.exp.PageException;
import railo.runtime.ext.tag.TagImpl;
import railo.runtime.functions.s3.StoreSetACL;
import railo.runtime.op.Caster;
import railo.runtime.op.Decision;
import railo.runtime.security.SecurityManager;
import railo.runtime.tag.util.FileUtil;
import railo.runtime.type.Array;
import railo.runtime.type.ArrayImpl;
import railo.runtime.type.Collection.Key;
import railo.runtime.type.Query;
import railo.runtime.type.QueryImpl;
import railo.runtime.type.UDF;
import railo.runtime.type.util.KeyConstants;
/**
* Handles interactions with directories.
*
*
*
**/
public final class Directory extends TagImpl {
public static final int TYPE_ALL = 0;
public static final int TYPE_FILE = 1;
public static final int TYPE_DIR = 2;
public static final ResourceFilter DIRECTORY_FILTER = new DirectoryResourceFilter();
public static final ResourceFilter FILE_FILTER = new FileResourceFilter();
private static final Key MODE = KeyConstants._mode;
private static final Key META = KeyConstants._meta;
private static final Key DATE_LAST_MODIFIED = KeyConstants._dateLastModified;
private static final Key ATTRIBUTES = KeyConstants._attributes;
private static final Key DIRECTORY = KeyConstants._directory;
public static final int LIST_INFO_QUERY_ALL = 1;
public static final int LIST_INFO_QUERY_NAME = 2;
public static final int LIST_INFO_ARRAY_NAME = 4;
public static final int LIST_INFO_ARRAY_PATH = 8;
public static final int NAMECONFLICT_DEFAULT = NAMECONFLICT_OVERWRITE; // default
/** Optional for action = "list". Ignored by all other actions. File extension filter applied to
** returned names. For example: *m. Only one mask filter can be applied at a time. */
private ResourceFilter filter;
private ResourceAndResourceNameFilter nameFilter;
/** The name of the directory to perform the action against. */
private Resource directory;
/** Defines the action to be taken with directory(ies) specified in directory. */
private String action="list";
/** Optional for action = "list". Ignored by all other actions. The query columns by which to sort
** the directory listing. Any combination of columns from query output can be specified in comma-separated list.
** You can specify ASC (ascending) or DESC (descending) as qualifiers for column names. ASC is the default */
private String sort;
/** Used with action = "Create" to define the permissions for a directory on UNIX and Linux
** platforms. Ignored on Windows. Options correspond to the octal values of the UNIX chmod command. From
** left to right, permissions are assigned for owner, group, and other. */
private int mode=-1;
/** Required for action = "rename". Ignored by all other actions. The new name of the directory
** specified in the directory attribute. */
private String strNewdirectory;
/** Required for action = "list". Ignored by all other actions. Name of output query for directory
** listing. */
private String name=null;
private boolean recurse=false;
private String serverPassword;
private int type=TYPE_ALL;
//private boolean listOnlyNames;
private int listInfo=LIST_INFO_QUERY_ALL;
//private int acl=S3Constants.ACL_UNKNOW;
private Object acl=null;
private int storage=S3Constants.STORAGE_UNKNOW;
private String destination;
private int nameconflict = NAMECONFLICT_DEFAULT;
private boolean createPath=true;
@Override
public void release() {
super.release();
acl=null;
storage=S3Constants.STORAGE_UNKNOW;
type=TYPE_ALL;
filter=null;
nameFilter=null;
destination=null;
directory=null;
action="list";
sort=null;
mode=-1;
strNewdirectory=null;
name=null;
recurse=false;
serverPassword=null;
listInfo=LIST_INFO_QUERY_ALL;
nameconflict = NAMECONFLICT_DEFAULT;
createPath=true;
}
public void setCreatepath(boolean createPath) {
this.createPath=createPath;
}
/**
* sets a filter
* @param filter
* @throws PageException
**/
public void setFilter(Object filter) throws PageException {
this.filter=nameFilter=UDFFilter.createResourceAndResourceNameFilter(filter);
}
public void setFilter(UDF filter) throws PageException {
this.filter=nameFilter=UDFFilter.createResourceAndResourceNameFilter(filter);
}
public void setFilter(String pattern) {
this.filter = nameFilter = UDFFilter.createResourceAndResourceNameFilter( pattern );
}
/** set the value acl
* used only for s3 resources, for all others ignored
* @param acl value to set
* @throws ApplicationException
* @Deprecated only exists for backward compatibility to old ra files.
**/
public void setAcl(String acl) throws ApplicationException {
this.acl=acl;
/*acl=acl.trim().toLowerCase();
if("private".equals(acl)) this.acl=S3Constants.ACL_PRIVATE;
else if("public-read".equals(acl)) this.acl=S3Constants.ACL_PRIVATE;
else if("public-read-write".equals(acl)) this.acl=S3Constants.ACL_PUBLIC_READ_WRITE;
else if("authenticated-read".equals(acl)) this.acl=S3Constants.ACL_AUTH_READ;
else throw new ApplicationException("invalid value for attribute acl ["+acl+"]",
"valid values are [private,public-read,public-read-write,authenticated-read]");*/
}
public void setAcl(Object acl) {
this.acl=acl;
}
public void setStoreacl(Object acl) {
this.acl=acl;
}
/** set the value storage
* used only for s3 resources, for all others ignored
* @param storage value to set
* @throws PageException
**/
public void setStorage(String storage) throws PageException {
try {
this.storage=S3.toIntStorage(storage);
} catch (S3Exception e) {
throw Caster.toPageException(e);
}
}
public void setStorelocation(String storage) throws PageException {
setStorage(storage);
}
public void setServerpassword(String serverPassword) {
this.serverPassword=serverPassword;
}
public void setListinfo(String strListinfo) {
strListinfo=strListinfo.trim().toLowerCase();
this.listInfo="name".equals(strListinfo)?LIST_INFO_QUERY_NAME:LIST_INFO_QUERY_ALL;
}
/** set the value directory
* The name of the directory to perform the action against.
* @param directory value to set
**/
public void setDirectory(String directory) {
this.directory=ResourceUtil.toResourceNotExisting(pageContext, directory);
//print.ln(this.directory);
}
/** set the value action
* Defines the action to be taken with directory(ies) specified in directory.
* @param action value to set
**/
public void setAction(String action) {
this.action=action.toLowerCase();
}
/** set the value sort
* Optional for action = "list". Ignored by all other actions. The query columns by which to sort
* the directory listing. Any combination of columns from query output can be specified in comma-separated list.
* You can specify ASC (ascending) or DESC (descending) as qualifiers for column names. ASC is the default
* @param sort value to set
**/
public void setSort(String sort) {
if(sort.trim().length()>0)
this.sort=sort;
}
/** set the value mode
* Used with action = "Create" to define the permissions for a directory on UNIX and Linux
* platforms. Ignored on Windows. Options correspond to the octal values of the UNIX chmod command. From
* left to right, permissions are assigned for owner, group, and other.
* @param mode value to set
* @throws PageException
**/
public void setMode(String mode) throws PageException {
try {
this.mode=ModeUtil.toOctalMode(mode);
}
catch (IOException e) {
throw Caster.toPageException(e);
}
}
/** set the value newdirectory
* Required for action = "rename". Ignored by all other actions. The new name of the directory
* specified in the directory attribute.
* @param newdirectory value to set
**/
public void setNewdirectory(String newdirectory) {
//this.newdirectory=ResourceUtil.toResourceNotExisting(pageContext ,newdirectory);
this.strNewdirectory=newdirectory;
}
public void setDestination(String destination) {
this.destination=destination;
}
/** set the value name
* Required for action = "list". Ignored by all other actions. Name of output query for directory
* listing.
* @param name value to set
**/
public void setName(String name) {
this.name=name;
}
/**
* @param recurse The recurse to set.
*/
public void setRecurse(boolean recurse) {
this.recurse = recurse;
}
/** set the value nameconflict
* Action to take if destination directory is the same as that of a file in the directory.
* @param nameconflict value to set
* @throws ApplicationException
**/
public void setNameconflict(String nameconflict) throws ApplicationException {
this.nameconflict = FileUtil.toNameConflict( nameconflict, NAMECONFLICT_UNDEFINED | NAMECONFLICT_ERROR | NAMECONFLICT_OVERWRITE, NAMECONFLICT_DEFAULT );
}
@Override
public int doStartTag() throws PageException {
//securityManager = pageContext.getConfig().getSecurityManager();
if(action.equals("list")) {
Object res=actionList(pageContext,directory,serverPassword,type,filter,nameFilter,listInfo,recurse,sort);
if(!StringUtil.isEmpty(name) && res!=null)pageContext.setVariable(name,res);
}
else if(action.equals("create")) actionCreate(pageContext,directory,serverPassword,createPath,mode,acl,storage, nameconflict);
else if(action.equals("delete")) actionDelete(pageContext,directory,recurse,serverPassword);
else if(action.equals("forcedelete")) actionDelete(pageContext,directory,true,serverPassword);
else if(action.equals("rename")) actionRename(pageContext,directory,strNewdirectory,serverPassword,createPath,acl,storage);
else if(action.equals("copy")) {
if(StringUtil.isEmpty(destination,true) && !StringUtil.isEmpty(strNewdirectory,true)) {
destination=strNewdirectory.trim();
}
actionCopy(pageContext,directory,destination,serverPassword,createPath,acl,storage,filter,recurse, nameconflict);
}
else throw new ApplicationException("invalid action ["+action+"] for the tag directory");
return SKIP_BODY;
}
@Override
public int doEndTag() {
return EVAL_PAGE;
}
/**
* list all files and directories inside a directory
* @throws PageException
*/
public static Object actionList(PageContext pageContext,Resource directory, String serverPassword, int type,ResourceFilter filter,ResourceAndResourceNameFilter nameFilter,
int listInfo,boolean recurse,String sort) throws PageException {
// check directory
SecurityManager securityManager = pageContext.getConfig().getSecurityManager();
securityManager.checkFileLocation(pageContext.getConfig(),directory,serverPassword);
if(type!=TYPE_ALL) {
ResourceFilter typeFilter = (type==TYPE_DIR)?DIRECTORY_FILTER:FILE_FILTER;
if(filter==null) filter=typeFilter;
else filter=new AndResourceFilter(new ResourceFilter[]{typeFilter,filter});
}
// create query Object
String[] names = new String[]{"name","size","type","dateLastModified","attributes","mode","directory"};
String[] types=new String[]{"VARCHAR","DOUBLE","VARCHAR","DATE","VARCHAR","VARCHAR","VARCHAR"};
boolean hasMeta=directory instanceof ResourceMetaData;
if(hasMeta){
names = new String[]{"name","size","type","dateLastModified","attributes","mode","directory","meta"};
types=new String[]{"VARCHAR","DOUBLE","VARCHAR","DATE","VARCHAR","VARCHAR","VARCHAR","OBJECT"};
}
Array array=null;
Query query=null;
Object rtn;
if(listInfo==LIST_INFO_QUERY_ALL || listInfo==LIST_INFO_QUERY_NAME){
boolean listOnlyNames=listInfo==LIST_INFO_QUERY_NAME;
rtn=query=new QueryImpl(
listOnlyNames?new String[]{"name"}:names,
listOnlyNames?new String[]{"VARCHAR"}:types,
0,"query");
}
else
rtn=array=new ArrayImpl();
if(!directory.exists()){
if(directory instanceof FileResource) return rtn;
throw new ApplicationException("directory ["+directory.toString()+"] doesn't exist");
}
if(!directory.isDirectory()){
if(directory instanceof FileResource) return rtn;
throw new ApplicationException("file ["+directory.toString()+"] exists, but isn't a directory");
}
if(!directory.isReadable()){
if(directory instanceof FileResource) return rtn;
throw new ApplicationException("no access to read directory ["+directory.toString()+"]");
}
long startNS=System.nanoTime();
try {
// Query All
if(listInfo==LIST_INFO_QUERY_ALL)
_fillQueryAll(query,directory,filter,0,hasMeta,recurse);
// Query Name
else if(listInfo==LIST_INFO_QUERY_NAME) {
if(recurse || type!=TYPE_ALL)_fillQueryNamesRec("",query, directory, filter, 0,recurse);
else _fillQueryNames(query, directory, nameFilter, 0);
}
//Array Name/Path
else if(listInfo==LIST_INFO_ARRAY_NAME || listInfo==LIST_INFO_ARRAY_PATH) {
boolean onlyName=listInfo==LIST_INFO_ARRAY_NAME;
if(!onlyName || recurse || type!=TYPE_ALL)_fillArrayPathOrName(array, directory, nameFilter, 0, recurse, onlyName);//QueryNamesRec("",query, directory, filter, 0,recurse);
else _fillArrayName(array, directory, nameFilter, 0);
}
} catch (IOException e) {
throw Caster.toPageException(e);
}
// sort
if(sort!=null && query!=null) {
String[] arr=sort.toLowerCase().split(",");
for(int i=arr.length-1;i>=0;i--) {
try {
String[] col=arr[i].trim().split("\\s+");
if(col.length==1)query.sort(col[0].trim());
else if(col.length==2) {
String order=col[1].toLowerCase().trim();
if(order.equals("asc"))
query.sort(col[0],railo.runtime.type.Query.ORDER_ASC);
else if(order.equals("desc"))
query.sort(col[0],railo.runtime.type.Query.ORDER_DESC);
else
throw new ApplicationException("invalid order type ["+col[1]+"]");
}
}
catch(Throwable t) {}
}
}
if(query!=null)query.setExecutionTime(System.nanoTime()-startNS);
return rtn;
}
private static int _fillQueryAll(Query query, Resource directory, ResourceFilter filter, int count, boolean hasMeta, boolean recurse) throws PageException, IOException {
//long start=System.currentTimeMillis();
Resource[] list=directory.listResources();
if(list==null || list.length==0) return count;
String dir=directory.getCanonicalPath();
// fill data to query
//query.addRow(list.length);
boolean isDir;
for(int i=0;i<list.length;i++) {
if(filter==null || filter.accept(list[i])) {
query.addRow(1);
count++;
query.setAt(KeyConstants._name,count,list[i].getName());
isDir=list[i].isDirectory();
query.setAt(KeyConstants._size,count,new Double(isDir?0:list[i].length()));
query.setAt(KeyConstants._type,count,isDir?"Dir":"File");
if(directory.getResourceProvider().isModeSupported()){
query.setAt(MODE,count,new ModeObjectWrap(list[i]));
}
query.setAt(DATE_LAST_MODIFIED,count,new Date(list[i].lastModified()));
query.setAt(ATTRIBUTES,count,getFileAttribute(list[i],true));
if(hasMeta){
query.setAt(META,count,((ResourceMetaData)list[i]).getMetaData());
}
query.setAt(DIRECTORY,count,dir);
}
if(recurse && list[i].isDirectory())
count=_fillQueryAll(query,list[i],filter,count,hasMeta,recurse);
}
return count;
}
// this method only exists for performance reasion
private static int _fillQueryNames(Query query, Resource directory, ResourceNameFilter filter, int count) throws PageException {
String[] list=directory.list();
if(list==null || list.length==0) return count;
for(int i=0;i<list.length;i++) {
if(filter==null || filter.accept(directory,list[i])) {
query.addRow(1);
count++;
query.setAt(KeyConstants._name,count,list[i]);
}
}
return count;
}
private static int _fillQueryNamesRec(String parent, Query query, Resource directory, ResourceFilter filter, int count, boolean recurse) throws PageException {
Resource[] list=directory.listResources();
if(list==null || list.length==0) return count;
for(int i=0;i<list.length;i++) {
if(filter==null || filter.accept(list[i])) {
query.addRow(1);
count++;
query.setAt(KeyConstants._name,count,parent.concat(list[i].getName()));
}
if(recurse && list[i].isDirectory())
count=_fillQueryNamesRec(parent + list[i].getName() + "/", query, list[i], filter, count, recurse);
}
return count;
}
private static int _fillArrayPathOrName(Array arr, Resource directory, ResourceFilter filter, int count, boolean recurse,boolean onlyName) throws PageException {
Resource[] list=directory.listResources();
if(list==null || list.length==0) return count;
for(int i=0;i<list.length;i++) {
if(filter==null || filter.accept(list[i])) {
arr.appendEL(onlyName?list[i].getName():list[i].getAbsolutePath());
count++;
}
if(recurse && list[i].isDirectory())
count=_fillArrayPathOrName(arr,list[i],filter,count,recurse,onlyName);
}
return count;
}
// this method only exists for performance reasion
private static int _fillArrayName(Array arr, Resource directory, ResourceNameFilter filter, int count) {
String[] list=directory.list();
if(list==null || list.length==0) return count;
for(int i=0;i<list.length;i++) {
if(filter==null || filter.accept(directory,list[i])) {
arr.appendEL(list[i]);
}
}
return count;
}
/**
* create a directory
* @throws PageException
*/
public static void actionCreate(PageContext pc,Resource directory,String serverPassword, boolean createPath, int mode, Object acl, int storage, int nameConflict) throws PageException {
SecurityManager securityManager = pc.getConfig().getSecurityManager();
securityManager.checkFileLocation(pc.getConfig(),directory,serverPassword);
if(directory.exists()) {
if(directory.isDirectory()) {
if ( nameConflict == NAMECONFLICT_SKIP )
return;
throw new ApplicationException("directory ["+directory.toString()+"] already exist");
}
else if(directory.isFile())
throw new ApplicationException("can't create directory ["+directory.toString()+"], it exist a file with same name");
}
//if(!directory.mkdirs()) throw new ApplicationException("can't create directory ["+directory.toString()+"]");
try {
directory.createDirectory(createPath);
} catch (IOException ioe) {
throw Caster.toPageException(ioe);
}
// set S3 stuff
setS3Attrs(directory,acl,storage);
// Set Mode
if(mode!=-1) {
try {
directory.setMode(mode);
//FileUtil.setMode(directory,mode);
} catch (IOException e) {
throw Caster.toPageException(e);
}
}
}
private static void setS3Attrs(Resource res,Object acl,int storage) throws PageException {
String scheme = res.getResourceProvider().getScheme();
if("s3".equalsIgnoreCase(scheme)){
S3Resource s3r=(S3Resource) res;
if(acl!=null){
try {
// old way
if(Decision.isString(acl)) {
if(Decision.isInteger(acl)) s3r.setACL(Caster.toIntValue(acl));
else s3r.setACL(S3.toIntACL(Caster.toString(acl)));
}
// new way
else {
StoreSetACL.invoke(s3r, acl);
}
} catch (IOException e) {
throw Caster.toPageException(e);
}
}
if(storage!=S3Constants.STORAGE_UNKNOW) s3r.setStorage(storage);
}
}
/**
* delete directory
* @param dir
* @param forceDelete
* @throws PageException
*/
public static void actionDelete(PageContext pc,Resource dir, boolean forceDelete,String serverPassword) throws PageException {
SecurityManager securityManager = pc.getConfig().getSecurityManager();
securityManager.checkFileLocation(pc.getConfig(),dir,serverPassword);
// directory doesn't exist
if(!dir.exists()) {
if(dir.isDirectory())
throw new ApplicationException("directory ["+dir.toString()+"] doesn't exist");
else if(dir.isFile())
throw new ApplicationException("file ["+dir.toString()+"] doesn't exist and isn't a directory");
}
// check if file
if(dir.isFile())
throw new ApplicationException("can't delete ["+dir.toString()+"], it isn't a directory it is a file");
// delete directory
try {
dir.remove(forceDelete);
} catch (IOException e) {
throw Caster.toPageException(e);
}
}
/**
* rename a directory to a new Name
* @throws PageException
*/
public static void actionRename(PageContext pc,Resource directory,String strNewdirectory,String serverPassword, boolean createPath, Object acl,int storage) throws PageException {
// check directory
SecurityManager securityManager = pc.getConfig().getSecurityManager();
securityManager.checkFileLocation(pc.getConfig(),directory,serverPassword);
if(!directory.exists())
throw new ApplicationException("the directory ["+directory.toString()+"] doesn't exist");
if(!directory.isDirectory())
throw new ApplicationException("the file ["+directory.toString()+"] exists, but it isn't a directory");
if(!directory.canRead())
throw new ApplicationException("no access to read directory ["+directory.toString()+"]");
if(strNewdirectory==null)
throw new ApplicationException("the attribute [newDirectory] is not defined");
// real to source
Resource newdirectory=toDestination(pc,strNewdirectory,directory);
securityManager.checkFileLocation(pc.getConfig(),newdirectory,serverPassword);
if(newdirectory.exists())
throw new ApplicationException("new directory ["+newdirectory.toString()+"] already exists");
if(createPath) {
newdirectory.getParentResource().mkdirs();
}
try {
directory.moveTo(newdirectory);
}
catch(Throwable t) {
throw Caster.toPageException(t);
}
// set S3 stuff
setS3Attrs(directory,acl,storage);
}
public static void actionCopy(PageContext pc,Resource directory,String strDestination,String serverPassword,boolean createPath, Object acl,int storage, ResourceFilter filter, boolean recurse, int nameconflict) throws PageException {
// check directory
SecurityManager securityManager = pc.getConfig().getSecurityManager();
securityManager.checkFileLocation(pc.getConfig(),directory,serverPassword);
if(!directory.exists())
throw new ApplicationException("directory ["+directory.toString()+"] doesn't exist");
if(!directory.isDirectory())
throw new ApplicationException("file ["+directory.toString()+"] exists, but isn't a directory");
if(!directory.canRead())
throw new ApplicationException("no access to read directory ["+directory.toString()+"]");
if(StringUtil.isEmpty(strDestination))
throw new ApplicationException("attribute destination is not defined");
// real to source
Resource newdirectory=toDestination(pc,strDestination,directory);
if ( nameconflict == NAMECONFLICT_ERROR && newdirectory.exists() )
throw new ApplicationException("new directory ["+newdirectory.toString()+"] already exist");
securityManager.checkFileLocation(pc.getConfig(),newdirectory,serverPassword);
try {
// has already a filter
if(filter!=null) {
if(recurse) filter=new OrResourceFilter(new ResourceFilter[]{
filter,DirectoryResourceFilter.FILTER
});
}
else {
if(!recurse)filter=new NotResourceFilter(DirectoryResourceFilter.FILTER);
}
if(!createPath) {
Resource p = newdirectory.getParentResource();
if(p!=null && !p.exists())
throw new ApplicationException("parent directory for ["+newdirectory+"] doesn't exist");
}
ResourceUtil.copyRecursive(directory, newdirectory,filter);
}
catch(Throwable t) {
throw new ApplicationException(t.getMessage());
}
// set S3 stuff
setS3Attrs(directory,acl,storage);
}
private static Resource toDestination(PageContext pageContext,String path, Resource source) {
if(source!=null && path.indexOf(File.separatorChar)==-1 && path.indexOf('/')==-1 && path.indexOf('\\')==-1) {
Resource p = source.getParentResource();
if(p!=null)return p.getRealResource(path);
}
return ResourceUtil.toResourceNotExisting(pageContext ,path);
}
private static String getFileAttribute(Resource file, boolean exists){
return exists && !file.isWriteable() ? "R".concat(file.isHidden() ? "H" : "") : file.isHidden() ? "H" : "";
}
/**
* @param strType the type to set
*/
public void setType(String strType) throws ApplicationException {
strType=strType.trim().toLowerCase();
if("all".equals(strType)) type=TYPE_ALL;
else if("dir".equals(strType)) type=TYPE_DIR;
else if("directory".equals(strType)) type=TYPE_DIR;
else if("file".equals(strType)) type=TYPE_FILE;
else throw new ApplicationException("invalid type ["+strType+"] for the tag directory");
}
}