清单 6. SrbFileObject 类
/**
* A file object implementation which uses direct file access.
*
* @author Vladmir Silva
*/
public class SrbFileObject
extends AbstractFileObject implements FileObject {
private Log log = LogFactory.getLog(SrbFileObject.class);
// SRB file object
private GeneralFile file;
// File info: Name, size, last modified
private FileName fileName;
private String filePath;
private MetaDataRecordList attribs;
// SRB Attributes
private Map fileAttributes = new HashMap();
// File Object children
private Map children = new TreeMap();
// used to parse SRB date: yyyy-MM-dd-HH.mm.ss
Calendar calendar = Calendar.getInstance();
/**
* For items which matched the query, met the conditions above,
* the following values will be returned.
*/
final String[] selectFieldNames = {
SRBMetaDataSet.FILE_NAME,
SRBMetaDataSet.FILE_COMMENTS,
SRBMetaDataSet.FILE_TYPE_NAME,
SRBMetaDataSet.SIZE,
SRBMetaDataSet.USER_NAME,
SRBMetaDataSet.FILE_LAST_ACCESS_TIMESTAMP,
SRBMetaDataSet.RESOURCE_NAME,
SRBMetaDataSet.
DEFINABLE_METADATA_FOR_FILES
};
MetaDataSelect selects[] =
MetaDataSet.newSelection(selectFieldNames);
/**
* Creates a non-root file.
*/
protected SrbFileObject(final SrbFileSystem fileSystem,
final FileName name)
throws FileSystemException {
super(name, fileSystem);
this.fileName = name;
this.filePath = UriParser.decode(name.getPath());
log.debug("Constructor for file path "
+ filePath + " file name=" + name);
}
/**
* Returns the local file that this file object represents.
*/
protected GeneralFile getGeneralFile() {
return file;
}
/*
* Get an SRB Attribute value from a query record
*/
private Object getSrbAttribute(MetaDataRecordList record, String key)
{
return record.getValue(record.getFieldIndex(key));
}
/**
* Set custom SRB attributes for a given File object
* @param f
* @param results
*/
synchronized private void setMetaAttributes(SrbFileObject f,
MetaDataRecordList results)
{
// Size and last mod date must be setup
for (int i = 0; i < selectFieldNames.length; i++) {
final Object value = getSrbAttribute
(results, selectFieldNames[i]);
if (value != null && value.toString().length() > 0)
{
f.fileAttributes.put(selectFieldNames[i], value);
}
}
}
/**
* Load File info from the SRB server
*/
private void statSelf() {
SrbFileSystem fs = (SrbFileSystem) getFileSystem();
file = FileFactory.newFile(fs.getSRBFileSystem(), filePath);
if (file.isDirectory()) {
injectType(FileType.FOLDER);
} else {
injectType(FileType.FILE);
}
if (!file.exists()) {
log.debug(file + " not found in server");
injectType(FileType.IMAGINARY);
return;
}
try {
/**
* The metadata records list for each file
* (directory, or other value
* the query selected for) is stored in this array.
*/
MetaDataRecordList[] results = file.query(selects);
// Extract size & date stamp from results
if (results != null) {
// Set custom Attributes
this.attribs = results[0];
setMetaAttributes(this, results[0]);
log.debug("File info for " + filePath
+ " meta data:" + fileAttributes);
}
} catch (Exception e) {
log.error(e);
}
}
/**
* Attaches this file object to its file resource.
*/
protected void doAttach() throws Exception {
// check parent
SrbFileObject parent = (SrbFileObject) getParent();
if (parent != null && parent.children != null) {
final SrbFileObject self =
(SrbFileObject) parent.children.get(
fileName.getBaseName());
if (self != null) {
log.debug("Found self " + self.getGeneralFile()
+ " in parent " + parent);
file = self.getGeneralFile();
}
}
if (file == null) {
log.debug("Loading info for file " + filePath + " from SRB");
statSelf();
}
}
/**
* Determines the type of the file, returns null if the file does not
* exist.
*/
protected FileType doGetType() throws Exception {
throw new IllegalStateException("this should not happen");
}
/**
* Load subfolder for this file object
* @param srbFileSystem
* @param file
* @throws Exception
*/
private void getSubFolders(SRBFileSystem srbFileSystem, GeneralFile file)
throws Exception
{
SRBFileSystem srbFileSysem = (SRBFileSystem) ((SrbFileSystem)
getFileSystem()).getSRBFileSystem();
MetaDataCondition conditions[] = new MetaDataCondition[1];
MetaDataSelect selects[] =
{MetaDataSet.newSelection(SRBMetaDataSet.
DIRECTORY_NAME)};
String path = (file.isDirectory()) ? file.getAbsolutePath() :
file.getParent();
conditions[0] = MetaDataSet.newCondition(
SRBMetaDataSet.PARENT_DIRECTORY_NAME,
MetaDataCondition.EQUAL, path);
MetaDataRecordList[] results =
srbFileSystem.query(conditions, selects);
if (results != null) {
for (int i = 0; i < results.length; i++) {
final String absPath = (String) getSrbAttribute(results[i],
SRBMetaDataSet.DIRECTORY_NAME);
final String dirName = absPath.substring(
absPath.lastIndexOf("/") + 1);
SrbFileObject fo = (SrbFileObject) getFileSystem()
.resolveFile(getFileSystem().getFileSystemManager()
.resolveName(getName(),
UriParser.encode(dirName),
NameScope.CHILD));
fo.attribs = results[i];
fo.file = FileFactory.newFile(srbFileSysem, absPath);
fo.injectType(FileType.FOLDER);
log.debug("Folder [" + i + "]=" + dirName + " abs path " +
absPath + " parent=" + filePath);
children.put(dirName, fo);
}
}
}
/**
* Get children information
*/
private void statChildren() throws FileSystemException {
SRBFileSystem srbFileSysem = (SRBFileSystem) ((SrbFileSystem)
getFileSystem()).getSRBFileSystem();
try {
// 2 queries are required: 1 for files, other for folders
MetaDataRecordList[] results = file.query(selects);
if (results != null) {
//children = new TreeMap();
for (int i = 0; i < results.length; i++) {
// File Name
final String name = (String) getSrbAttribute(results[i],
SRBMetaDataSet.FILE_NAME);
// File Size
final long size = Long.parseLong((String) getSrbAttribute(
results[i], SRBMetaDataSet.SIZE));
// time stamp
final String sDate = (String) getSrbAttribute(results[i],
SRBMetaDataSet.FILE_LAST_ACCESS_TIMESTAMP);
// type
final String type = (String) getSrbAttribute(results[i],
SRBMetaDataSet.FILE_TYPE_NAME);
calendar.setTime(
new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss").
parse(sDate));
final long lastModified =
calendar.getTimeInMillis();
// Add child
SrbFileObject fo = (SrbFileObject) getFileSystem().
resolveFile(getFileSystem().
getFileSystemManager().resolveName(
getName(),
UriParser.encode(name),
NameScope.CHILD));
fo.attribs = results[i];
fo.file = FileFactory.newFile(srbFileSysem
, filePath + "/" + name);
fo.injectType(FileType.FILE);
setMetaAttributes(fo, results[i]);
log.debug("File[" + i + "]="
+ name + " Size=" + size
+ " Last Mod:" + lastModified + " Type:" + type);
children.put(name, fo);
}
}
// query folders
getSubFolders(srbFileSysem, file);
} catch (Exception e) {
throw new FileSystemException (
"vfs.provider.srb/get-children.error",file);
}
}
/**
* Returns the children of the file.
*/
protected String[] doListChildren() throws Exception {
// use doListChildrenResolved for performance
return null;
}
/**
* Lists the children of this file.
*/
protected FileObject[] doListChildrenResolved() throws Exception {
// List the contents of the folder
statChildren();
return (SrbFileObject[]) children.values().toArray(
new SrbFileObject[children.size()]);
}
/**
* Deletes this file, and all children.
*/
protected void doDelete() throws Exception {
if (!file.delete()) {
throw new FileSystemException(
"vfs.provider.local/delete-file.error", file);
}
}
/**
* rename this file
*/
protected void doRename(FileObject newfile) throws Exception {
if (!file.renameTo(((SrbFileObject) newfile).getGeneralFile())) {
throw new FileSystemException(
"vfs.provider.local/rename-file.error",
new String[] {file.toString(),newfile.toString()});
}
}
/**
* Creates this folder.
*/
protected void doCreateFolder() throws Exception {
if (!file.mkdirs()) {
throw new FileSystemException(
"vfs.provider.local/create-folder.error", file);
}
}
/**
* Determines if this file can be written to.
*/
protected boolean doIsWriteable() throws FileSystemException {
return file.canWrite();
}
/**
* Determines if this file is hidden.
*/
protected boolean doIsHidden() {
return file.isHidden();
}
/**
* Determines if this file can be read.
*/
protected boolean doIsReadable() throws FileSystemException {
return file.canRead();
}
/**
* Gets the last modified time of this file.
*/
protected long doGetLastModifiedTime() throws FileSystemException {
if (attribs == null) {
log.error(
"Assertion failed - NULL meta data record list for file:"
+ file);
return -1;
}
try {
// SRB dirs don't have a time stamp
String sDate = (String) getSrbAttribute(attribs,
SRBMetaDataSet.FILE_LAST_ACCESS_TIMESTAMP);
// parse SRB date: yyyy-MM-dd-HH.mm.ss
calendar.setTime(
new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss").parse(sDate));
return calendar.getTimeInMillis();
} catch (Exception e) {
throw new FileSystemException(e.getMessage(), e);
}
}
/**
* Sets the last modified time of this file.
*/
protected void doSetLastModifiedTime(final long modtime) throws
FileSystemException {
file.setLastModified(modtime);
}
/**
* Creates an input stream to read the content from.
*/
protected InputStream doGetInputStream() throws Exception {
return new SRBFileInputStream((SRBFile) file);
}
/**
* Creates an output stream to write the file content to.
*/
protected OutputStream doGetOutputStream(boolean bAppend)
throws Exception {
return new SRBFileOutputStream((SRBFile) file);
}
/**
* Returns the size of the file content (in bytes).
*/
protected long doGetContentSize() throws Exception {
//return getSize(); // fileSize;
if (attribs == null) {
log.error(
"Assertion failed - NULL meta data record list for file:"
+ file);
return -1;
}
return Long.parseLong((String) getSrbAttribute(attribs,
SRBMetaDataSet.SIZE));
}
/**
* Returns the attributes of this file.
*
* This implementation always returns an empty map.
*/
protected Map doGetAttributes() throws Exception {
return fileAttributes;
}
/**
* Called when the type or content of this file changes.
*/
protected void onChange() throws Exception {
log.debug("file=" + file);
statSelf();
}
}
|