/*
* Copyright 2010 netling project <http://netling.org>
*
* 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.
*
* This file may incorporate work covered by the following copyright and
* permission notice:
*
* 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.netling.ftp;
import java.util.Calendar;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Map.Entry;
/***
* The FTPFile class is used to represent information about files stored
* on an FTP server.
* <p>
* <p>
* @see FTPFileEntryParser
* @see FTPClient#listFiles
***/
public class FTPFile {
/**
* An enumeration that represents the file type
*/
public enum Type {
FILE,
DIRECTORY,
SYMBOLIC_LINK,
UNKNOWN
}
/**
* An enumeration that represents the access permission type
*/
public enum Access {
USER,
GROUP,
WORLD;
}
/**
* An enumeration that represents the permission level
*/
public enum Permission {
READ,
WRITE,
EXECUTE;
public String toString() {
if (this==READ)
return "r";
else if (this==WRITE)
return "w";
else
return "x";
};
}
private Type type;
private int hardLinkCount;
private long size;
private String rawListing, user, group, name, link;
private Calendar date;
/** Permission map (typedefs would be nice here if we had them!) */
private EnumMap<Access, EnumSet<Permission>> permissions;
/*** Creates an empty FTPFile. ***/
public FTPFile()
{
permissions = new EnumMap<FTPFile.Access, EnumSet<Permission>>(Access.class);
permissions.put(Access.USER, EnumSet.noneOf(Permission.class));
permissions.put(Access.GROUP, EnumSet.noneOf(Permission.class));
permissions.put(Access.WORLD, EnumSet.noneOf(Permission.class));
rawListing = null;
type = Type.UNKNOWN;
hardLinkCount = 0;
size = 0;
user = null;
group = null;
date = null;
name = null;
}
/***
* Set the original FTP server raw listing from which the FTPFile was
* created.
*
* @param rawListing The raw FTP server listing.
***/
public void setRawListing(String rawListing)
{
this.rawListing = rawListing;
}
/***
* Get the original FTP server raw listing used to initialize the FTPFile.
*
* @return The original FTP server raw listing used to initialize the
* FTPFile.
***/
public String getRawListing()
{
return rawListing;
}
/***
* Determine if the file is a directory.
*
* @return True if the file is of type <code>DIRECTORY_TYPE</code>, false if
* not.
***/
public boolean isDirectory()
{
return (type == Type.DIRECTORY);
}
/***
* Determine if the file is a regular file.
*
* @return True if the file is of type <code>FILE_TYPE</code>, false if
* not.
***/
public boolean isFile()
{
return (type == Type.FILE);
}
/***
* Determine if the file is a symbolic link.
*
* @return True if the file is of type <code>UNKNOWN_TYPE</code>, false if
* not.
***/
public boolean isSymbolicLink()
{
return (type == Type.SYMBOLIC_LINK);
}
/***
* Determine if the type of the file is unknown.
*
* @return True if the file is of type <code>UNKNOWN_TYPE</code>, false if
* not.
***/
public boolean isUnknown()
{
return (type == Type.UNKNOWN);
}
/***
* Set the type of the file
*
* @param type The {@link Type} instance representing the type of the file.
***/
public void setType(final Type type)
{
this.type = type;
}
/***
* Return the type of the file
* e.g., if it is a directory, a regular file, or a symbolic link.
*
* @return The type of the file.
***/
public Type getType()
{
return type;
}
/***
* Set the name of the file.
*
* @param name The name of the file.
***/
public void setName(String name)
{
this.name = name;
}
/***
* Return the name of the file.
*
* @return The name of the file.
***/
public String getName()
{
return name;
}
/**
* Set the file size in bytes.
* @param size The file size in bytes.
*/
public void setSize(long size)
{
this.size = size;
}
/***
* Return the file size in bytes.
*
* @return The file size in bytes.
***/
public long getSize()
{
return size;
}
/***
* Set the number of hard links to this file. This is not to be
* confused with symbolic links.
*
* @param links The number of hard links to this file.
***/
public void setHardLinkCount(int links)
{
hardLinkCount = links;
}
/***
* Return the number of hard links to this file. This is not to be
* confused with symbolic links.
*
* @return The number of hard links to this file.
***/
public int getHardLinkCount()
{
return hardLinkCount;
}
/***
* Set the name of the group owning the file. This may be
* a string representation of the group number.
*
* @param group The name of the group owning the file.
***/
public void setGroup(String group)
{
this.group = group;
}
/***
* Returns the name of the group owning the file. Sometimes this will be
* a string representation of the group number.
*
* @return The name of the group owning the file.
***/
public String getGroup()
{
return group;
}
/***
* Set the name of the user owning the file. This may be
* a string representation of the user number;
*
* @param user The name of the user owning the file.
***/
public void setUser(String user)
{
this.user = user;
}
/***
* Returns the name of the user owning the file. Sometimes this will be
* a string representation of the user number.
*
* @return The name of the user owning the file.
***/
public String getUser()
{
return user;
}
/***
* If the FTPFile is a symbolic link, use this method to set the name of the
* file being pointed to by the symbolic link.
*
* @param link The file pointed to by the symbolic link.
***/
public void setLink(String link)
{
this.link = link;
}
/***
* If the FTPFile is a symbolic link, this method returns the name of the
* file being pointed to by the symbolic link. Otherwise it returns null.
*
* @return The file pointed to by the symbolic link (null if the FTPFile
* is not a symbolic link).
***/
public String getLink()
{
return link;
}
/***
* Set the file timestamp. This usually the last modification time.
* The parameter is not cloned, so do not alter its value after calling
* this method.
*
* @param date A Calendar instance representing the file timestamp.
***/
public void setTimestamp(Calendar date)
{
this.date = date;
}
/***
* Returns the file timestamp. This usually the last modification time.
*
* @return A Calendar instance representing the file timestamp.
***/
public Calendar getTimestamp()
{
return date;
}
/***
* Set the given permission for the specified access group.
*
* @param access The access group (An {@link Access} instance)
* @param permission The access permission (A {@link Permission} instance)
* TODO do we need a removePerm?
*
***/
public void setPermission(Access access, Permission permission)
{
EnumSet<Permission> perms = permissions.get(access);
perms.add(permission);
permissions.put(access, perms);
}
/***
* Determines if the given access group has the given access permission.
*
* @param access The access group (An {@link Access} instance)
* @param permission A {@link Permission} instance
***/
public boolean hasPermission(Access access, Permission permission)
{
EnumSet<Permission> perms = permissions.get(access);
if (perms == null)
return false;
else
return perms.contains(permission);
}
/***
* Returns a string representation of the FTPFile information. This
* will be the raw FTP server listing that was used to initialize the
* FTPFile instance.
*
* @return A string representation of the FTPFile information.
***/
@Override
public String toString()
{
return rawListing;
}
/**
* Return the permissions as a human-readable string
* @ TODO test
* @return
*/
public String getPermissionsString() {
final StringBuilder buf= new StringBuilder();
// Rely on the natural ordering of EnumMap iterators
for (final Entry<Access, EnumSet<Permission>> access : permissions.entrySet()) {
final EnumSet<Permission> permSet = access.getValue();
for (Permission permission : Permission.values()) {
if (permSet.contains(permission))
buf.append(permission);
else
buf.append("-");
}
}
return buf.toString();
}
}