0001: /*
0002: * The contents of this file are subject to the
0003: * Mozilla Public License Version 1.1 (the "License");
0004: * you may not use this file except in compliance with the License.
0005: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
0006: *
0007: * Software distributed under the License is distributed on an "AS IS"
0008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
0009: * See the License for the specific language governing rights and
0010: * limitations under the License.
0011: *
0012: * The Initial Developer of the Original Code is Simulacra Media Ltd.
0013: * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
0014: *
0015: * All Rights Reserved.
0016: *
0017: * Contributor(s):
0018: */
0019: package org.openharmonise.vfs;
0020:
0021: import java.util.*;
0022:
0023: import org.openharmonise.vfs.event.*;
0024: import org.openharmonise.vfs.metadata.*;
0025: import org.openharmonise.vfs.status.*;
0026:
0027: /**
0028: * A representation of a file in a Virtual File System.
0029: *
0030: * @author Matthew Large
0031: * @version $Revision: 1.1 $
0032: *
0033: */
0034: public class VirtualFile {
0035:
0036: /**
0037: * The virtual file system that this virtual file is attached to.
0038: */
0039: protected AbstractVirtualFileSystem m_vfs = null;
0040:
0041: /**
0042: * The children of this virtual file, if it is a collection.
0043: */
0044: private ArrayList m_children = new ArrayList(5);
0045:
0046: /**
0047: * The property instances attached to this virtual file.
0048: */
0049: private HashMap m_properties = new HashMap(5);
0050:
0051: /**
0052: * The path to the parent collection of this virtual file, e.g. if the full path is '/webdav/Documents/doc1' then this will be '/webdav/Documents'.
0053: */
0054: private String m_sFilePath;
0055:
0056: /**
0057: * The name of this virtual file, e.g. if the full path is '/webdav/Documents/doc1' then this will be 'doc1'.
0058: */
0059: private String m_sFileName;
0060:
0061: /**
0062: * The complete path of this virtual file.
0063: */
0064: private String m_sFullPath;
0065:
0066: /**
0067: * The owner of the exclusive lock on this virtual file, if there is one. This should be the full path to the virtual file for the principal representing the user, if the underlying file system supports this.
0068: */
0069: private String m_sLockOwner = null;
0070:
0071: /**
0072: * The unique lock token for the exclusive lock on this virtual file, if there is one.
0073: */
0074: private String m_sLockToken = null;
0075:
0076: /**
0077: * true if the content for this virtual file is populated.
0078: */
0079: private boolean m_bContentPopulated = false;
0080:
0081: /**
0082: * true if the children list for this virtual file, if it is a collection, is populated.
0083: */
0084: private boolean m_bChildrenPopulated = false;
0085:
0086: /**
0087: * true if the metadata for this virtual file is populated.
0088: */
0089: private boolean m_bMetadataPopulated = false;
0090:
0091: /**
0092: * true if the content for this virtual file has changed since it was populated.
0093: */
0094: private boolean m_bContentChanged = false;
0095:
0096: /**
0097: * true if the metedata for this virtual file has changed since it was populated.
0098: */
0099: private boolean m_bMetadataChanged = false;
0100:
0101: /**
0102: * true if this virtual file is a collection.
0103: */
0104: private boolean m_bIsDirectory = false;
0105:
0106: /**
0107: * The content for this virtual file.
0108: */
0109: private byte[] m_content = null;
0110:
0111: /**
0112: * The list of {@link VirtualFileListener} objects attached to this virtual file.
0113: */
0114: private ArrayList m_listeners = new ArrayList();
0115:
0116: /**
0117: * The state of a pending virtual file.
0118: */
0119: public static String STATE_PENDING = "PENDING";
0120:
0121: /**
0122: * The state of a live virtual file.
0123: */
0124: public static String STATE_LIVE = "LIVE";
0125:
0126: /**
0127: * The state of a historical virtual file.
0128: */
0129: public static String STATE_HISTORICAL = "HISTORICAL";
0130:
0131: /**
0132: * The current state of this virtual file.
0133: */
0134: private String m_sState = VirtualFile.STATE_LIVE;
0135:
0136: /**
0137: * true if this virtual file is versionable.
0138: */
0139: private boolean m_bVersionable = false;
0140:
0141: /**
0142: * true if this virtual file is orderable.
0143: */
0144: private boolean m_bOrderableDirectory = false;
0145:
0146: /**
0147: * List of methods allowed on this virtual file.
0148: */
0149: private ArrayList m_allowedMethods = new ArrayList();
0150:
0151: /**
0152: * Timestamp of the last time the allow methods list was populated.
0153: */
0154: private Date m_dtAllowedMethodsTimeStamp = null;
0155:
0156: /**
0157: * Submit method identifier for allowed methods.
0158: */
0159: public static String METHOD_SYNC = "SYNC";
0160:
0161: /**
0162: * Delete method identifier for allowed methods.
0163: */
0164: public static String METHOD_DELETE = "DELETE";
0165:
0166: /**
0167: * Move method identifier for allowed methods.
0168: */
0169: public static String METHOD_MOVE = "MOVE";
0170:
0171: /**
0172: * Copy method identifier for allowed methods.
0173: */
0174: public static String METHOD_COPY = "COPY";
0175:
0176: /**
0177: * Create collection method identifier for allowed methods.
0178: */
0179: public static String METHOD_MKDIR = "MKDIR";
0180:
0181: /**
0182: * Lock method identifier for allowed methods.
0183: */
0184: public static String METHOD_LOCK = "LOCK";
0185:
0186: /**
0187: * Unlock method identifier for allowed methods.
0188: */
0189: public static String METHOD_UNLOCK = "UNLOCK";
0190:
0191: /**
0192: * Create shortcut method identifier for allowed methods.
0193: */
0194: public static String METHOD_SHORTCUT = "SHORTCUT";
0195:
0196: /**
0197: * Set children order method identifier for allowed methods.
0198: */
0199: public static String METHOD_SET_CHILD_ORDER = "SET_CHILD_ORDER";
0200:
0201: /**
0202: * Checkin method identifier for allowed methods.
0203: */
0204: public static String METHOD_CHECKIN = "CHECKIN";
0205:
0206: /**
0207: * Tag method identifier for allowed methods.
0208: */
0209: public static String METHOD_TAG = "TAG";
0210:
0211: /**
0212: * Order method identifier for allowed methods.
0213: */
0214: public static String METHOD_ORDER = "ORDER";
0215:
0216: /**
0217: * Reject method identifier for allowed methods.
0218: */
0219: public static String METHOD_REJECT = "REJECT";
0220:
0221: /**
0222: * Checkout method identifier for allowed methods.
0223: */
0224: public static String METHOD_CHECKOUT = "CHECKOUT";
0225:
0226: /**
0227: * Checkout method identifier for allowed methods.
0228: */
0229: public static String METHOD_RENAME = "RENAME";
0230:
0231: /**
0232: * Add method identifier for allowed methods.
0233: */
0234: public static String METHOD_ADD = "ADD";
0235:
0236: /**
0237: * Get method identifier for allowed methods.
0238: */
0239: public static String METHOD_GET = "GET";
0240:
0241: /**
0242: * Search method identifier for allowed methods.
0243: */
0244: public static String METHOD_SEARCH = "SEARCH";
0245:
0246: public static int EVENT_NOTHING = 0;
0247:
0248: public static int EVENT_ADDITION = 1;
0249:
0250: public static int EVENT_REMOVAL = 2;
0251:
0252: /**
0253: * true if the lock information for this virtual file is populated.
0254: */
0255: private boolean m_bPopulateLocked = false;
0256:
0257: private boolean m_bIsVirtualDirectory = false;
0258:
0259: /**
0260: * Constructs a Virtual File.
0261: *
0262: * @param sFullPath FullPath of the file
0263: */
0264: public VirtualFile(String sFullPath) {
0265: super ();
0266: this .setFullPath(sFullPath);
0267: }
0268:
0269: /**
0270: * Constructs a Virtual File.
0271: */
0272: public VirtualFile() {
0273: super ();
0274: }
0275:
0276: /**
0277: * Discards any changes that may have been made to this virtual file
0278: * since it was populate. The any information subsequently requested
0279: * will be repopulated from the underlying file system.
0280: *
0281: */
0282: protected void discardChanges() {
0283: if (this .isChanged()) {
0284: this .clearFile();
0285: }
0286: }
0287:
0288: /**
0289: * Clears all of the information about this virtual file and resets
0290: * all of the populated booleans to false.
0291: *
0292: */
0293: public void clearFile() {
0294: m_bContentPopulated = false;
0295: m_bChildrenPopulated = false;
0296: m_bMetadataPopulated = false;
0297: this .m_children.clear();
0298: this .m_content = null;
0299: this .m_properties.clear();
0300: this .m_bContentChanged = false;
0301: this .m_bMetadataChanged = false;
0302: this
0303: .fireVirtualFileEvent(VirtualFileEvent.FILE_CHANGES_DISCARDED);
0304: }
0305:
0306: /**
0307: * Checks if this virtual file's lock information has been populated.
0308: *
0309: * @return true if this virtual file's lock information has been populated
0310: */
0311: public boolean isPopulateLocked() {
0312: return this .m_bPopulateLocked;
0313: }
0314:
0315: /**
0316: * Sets the lock populated information for this virtual file.
0317: *
0318: * @param bPopulateLocked Set to true to set that this virtual file's lock information has been populated.
0319: */
0320: public void setPopulateLocked(boolean bPopulateLocked) {
0321: this .m_bPopulateLocked = bPopulateLocked;
0322: }
0323:
0324: /**
0325: * Sets the full path of this virtual file.
0326: *
0327: * @param sFullPath The full path for this virtual file
0328: */
0329: public void setFullPath(String sFullPath) {
0330: String sFilePath = null;
0331: String sFileName = null;
0332: if (sFullPath.endsWith("/")) {
0333: String sTemp = sFullPath;
0334: sTemp = sTemp.substring(0, sTemp.length() - 1);
0335: sFilePath = sTemp.substring(0, sTemp.lastIndexOf("/"
0336: .charAt(0)));
0337: sFileName = sTemp.substring(sTemp
0338: .lastIndexOf("/".charAt(0)));
0339: } else {
0340: String sTemp = sFullPath;
0341: sFilePath = sTemp.substring(0, sTemp.lastIndexOf("/"
0342: .charAt(0)));
0343: sFileName = sTemp.substring(sTemp
0344: .lastIndexOf("/".charAt(0)));
0345: }
0346: this .m_sFilePath = sFilePath;
0347: if (sFullPath.endsWith("/")) {
0348: sFullPath = sFullPath.substring(0, sFullPath.length() - 1);
0349: }
0350: this .m_sFullPath = sFullPath;
0351: if (sFileName.endsWith("/")) {
0352: sFileName = sFileName.substring(0, sFileName.length() - 1);
0353: }
0354: if (sFileName.startsWith("/")) {
0355: sFileName = sFileName.substring(1, sFileName.length());
0356: }
0357: this .m_sFileName = sFileName;
0358: }
0359:
0360: /**
0361: * Adds a path to this virtual file's children list.
0362: *
0363: * @param sURI Path to add to this virtual file's children list
0364: */
0365: public void addChild(String sURI) {
0366: this .m_children.add(sURI);
0367: //this.fireVirtualFileEvent(VirtualFileEvent.FILE_MEMBERS_CHANGED);
0368: }
0369:
0370: /**
0371: * Removes a path from this virtual file's children list.
0372: *
0373: * @param sURI Path to remove from this virtual file's children list
0374: */
0375: public void removeChild(String sURI) {
0376: this .m_children.remove(sURI);
0377: }
0378:
0379: /**
0380: * Checks if this virtual file has a path as one of its children.
0381: *
0382: * @param sURI Path to check
0383: * @return true if the given path is a child of this virtual file
0384: */
0385: public boolean hasChild(String sURI) {
0386: return this .m_children.contains(sURI);
0387: }
0388:
0389: /**
0390: * Returns a list of the paths that are children of this virtual file.
0391: *
0392: * @return List of virtual file paths
0393: */
0394: public List getChildren() {
0395: if (this .isDirectory() && !this .m_bChildrenPopulated) {
0396: this .m_vfs.fullyPopulateFileChildren(this );
0397: }
0398: return (List) this .m_children.clone();
0399: }
0400:
0401: /**
0402: * Sets the order of the children of this virtual file. This method
0403: * will fail if this is not a collection which is orderable or if the
0404: * contents of the suplied list of paths does not match the list of
0405: * child paths for this collection.
0406: *
0407: * @param children List of paths in the order to be set
0408: * @return true if the method was successful
0409: */
0410: public StatusData setChildrenOrder(List children) {
0411: VFSStatus retnStatus = new VFSStatus();
0412: retnStatus.setMethodName(METHOD_ORDER);
0413:
0414: if (this .isDirectory() && this .isOrderableDirectory()
0415: && this .m_children.containsAll(children)
0416: && children.containsAll(this .m_children)) {
0417: this .m_children = (ArrayList) children;
0418: StatusData vfsStatus = this .m_vfs.orderVirtualFileChildren(
0419: children, this );
0420: retnStatus.addStatusData(vfsStatus);
0421: this .m_children.clear();
0422: this .m_bChildrenPopulated = false;
0423: this
0424: .fireVirtualFileEvent(VirtualFileEvent.FILE_MEMBERS_CHANGED);
0425: }
0426:
0427: return retnStatus;
0428: }
0429:
0430: /**
0431: * Adds a {@link PropertyInstance} to the metadata for this vitual
0432: * file.
0433: *
0434: * @param prop {@link PropertyInstance} to add to this virtual file
0435: */
0436: public void addProperty(PropertyInstance prop) {
0437: this .m_properties.put(prop.getNamespaceURI() + "#"
0438: + prop.getName(), prop);
0439: prop.setVirtualFile(this );
0440: }
0441:
0442: /**
0443: * Clears all the metadata for this virtual file.
0444: *
0445: */
0446: protected void clearAllProperties() {
0447: this .m_properties.clear();
0448: }
0449:
0450: /**
0451: * Removes a {@link PropertyInstance} from the metadata for this
0452: * virtual file.
0453: *
0454: * @param sNamespaceURI Namespace of the {@link PropertyInstance} to be removed
0455: * @param sName Name of the {@link PropertyInstance} to be removed
0456: */
0457: public void removeProperty(String sNamespaceURI, String sName) {
0458: this .m_properties.remove(sNamespaceURI + "#" + sName);
0459: }
0460:
0461: /**
0462: * Returns a {@link PropertyInstance} from the metadata for this
0463: * virtual file which matches the given namespace and name.
0464: *
0465: * @param sNamespaceURI Namespace of the {@link PropertyInstance} to be returned
0466: * @param sName Name of the {@link PropertyInstance} to be returned
0467: * @return null if no {@link PropertyInstance} was found in this virtual file's metadata matching the given namespace and name
0468: */
0469: public PropertyInstance getProperty(String sNamespaceURI,
0470: String sName) {
0471: PropertyInstance prop = (PropertyInstance) this .m_properties
0472: .get(sNamespaceURI + "#" + sName);
0473:
0474: if (!this .isMetadataPopulated() && prop == null
0475: && this .m_vfs != null) {
0476: this .m_vfs.fullyPopulateFileMetadata(this );
0477: prop = (PropertyInstance) this .m_properties
0478: .get(sNamespaceURI + "#" + sName);
0479: }
0480:
0481: return prop;
0482: }
0483:
0484: /**
0485: * Returns a list of all the {@link PropertyInstance} objects in this
0486: * virtual file's metadata.
0487: *
0488: * @return List of {@link PropertyInstance} objects
0489: */
0490: public List getProperties() {
0491: if (!this .m_bMetadataPopulated) {
0492: this .m_vfs.fullyPopulateFileMetadata(this );
0493: }
0494: return new ArrayList(this .m_properties.values());
0495: }
0496:
0497: /**
0498: * Gives the file a hook to the file system it belongs to.
0499: *
0500: * @param vfs Virtual file system that the file belongs to
0501: */
0502: public void setVFS(AbstractVirtualFileSystem vfs) {
0503: this .m_vfs = vfs;
0504: }
0505:
0506: /**
0507: * Returns the {@link AbstractVirtualFileSystem} that this virtual file
0508: * belongs to.
0509: *
0510: * @return Virtual file system that this virtual file belongs to
0511: */
0512: public AbstractVirtualFileSystem getVFS() {
0513: return this .m_vfs;
0514: }
0515:
0516: /**
0517: * Checks if the file has any listeners.
0518: *
0519: * @return true if the file has any listeners
0520: */
0521: public boolean hasVirtualFileListeners() {
0522: return this .m_listeners.size() > 0;
0523: }
0524:
0525: /**
0526: * Checks if the in memory file has changed in anyway since it either came from
0527: * the Virtual File System or since it was last synchronized.
0528: *
0529: * @return true if the file has changed
0530: */
0531: public boolean isChanged() {
0532: return this .m_bContentChanged || this .m_bMetadataChanged;
0533: }
0534:
0535: /**
0536: * Checks if the content for this virtual file has changes since it
0537: * was last populated.
0538: *
0539: * @return true if the content has changed
0540: */
0541: public boolean isContentChanged() {
0542: return this .m_bContentChanged;
0543: }
0544:
0545: /**
0546: * Checks if the metadata for this virtual file has changed since it
0547: * was last populated.
0548: *
0549: * @return true if the metadata has changed
0550: */
0551: public boolean isMetadataChanged() {
0552: return this .m_bMetadataChanged;
0553: }
0554:
0555: /**
0556: * Checks if the file is fully populated, to allow for lazy partial instantiation.
0557: *
0558: * @return true if the file is fully populated
0559: */
0560: public boolean isFullyPopulated() {
0561: return this .m_bChildrenPopulated && this .m_bContentPopulated
0562: && this .m_bMetadataPopulated;
0563: }
0564:
0565: /**
0566: * Checks if the list of children for this virtual file has been
0567: * populated.
0568: *
0569: * @return true if the list of children has been populated
0570: */
0571: protected boolean isChildrenPopulated() {
0572: return this .m_bChildrenPopulated;
0573: }
0574:
0575: /**
0576: * Sets that the list of children for this virtual file has been
0577: * populated.
0578: *
0579: * @param bChildrenPopulated Set to true to set that the list of children has been populated
0580: */
0581: protected void setChildrenPopulated(boolean bChildrenPopulated) {
0582: this .m_bChildrenPopulated = bChildrenPopulated;
0583: }
0584:
0585: /**
0586: * Checks if the content for this virtual file has been populated.
0587: *
0588: * @return true if the content has been populated
0589: */
0590: protected boolean isContentPopulated() {
0591: return this .m_bContentPopulated;
0592: }
0593:
0594: /**
0595: * Sets that the content for this virtual file has been populated.
0596: *
0597: * @param bContentPopulated Set to true to set that the content has been populated
0598: */
0599: protected void setContentPopulated(boolean bContentPopulated) {
0600: this .m_bContentPopulated = bContentPopulated;
0601: }
0602:
0603: /**
0604: * Checks if the metadata for this virtual file has been populated.
0605: *
0606: * @return true if the metadata has been populated
0607: */
0608: protected boolean isMetadataPopulated() {
0609: return this .m_bMetadataPopulated;
0610: }
0611:
0612: /**
0613: * Sets that the metadata for this virtual file has been populated.
0614: *
0615: * @param bMetadataPopulated Set to true to set that the metadata has been populated
0616: */
0617: protected void setMetadataPopulated(boolean bMetadataPopulated) {
0618: this .m_bMetadataPopulated = bMetadataPopulated;
0619: }
0620:
0621: /**
0622: * Gets the full path of the file.
0623: *
0624: * @return Fullpath of the file
0625: */
0626: public String getFullPath() {
0627: return this .m_sFullPath;
0628: }
0629:
0630: /**
0631: * Copies the file to a new path with a new filename.
0632: *
0633: * @param sNewPath Path to copy to
0634: * @param sNewFilename Filename to give the new copy
0635: * @return true if the method was successful
0636: */
0637: public StatusData copy(String sNewPath, String sNewFilename) {
0638: VFSStatus retnStatus = new VFSStatus();
0639: retnStatus.setMethodName(METHOD_COPY);
0640:
0641: String sOldPath = this .getFullPath();
0642: VirtualFile vfOldParent = this .m_vfs.getVirtualFile(
0643: this .getFilePath()).getResource();
0644: VirtualFile vfNewParent = this .m_vfs.getVirtualFile(sNewPath)
0645: .getResource();
0646: StatusData vfsStatus = this .m_vfs.copyVirtualFile(this
0647: .getFullPath(), sNewPath + "/" + sNewFilename);
0648: retnStatus.addStatusData(vfsStatus);
0649: if (retnStatus.isOK()) {
0650: String sNewFilePath = sNewPath + "/" + this .getFileName();
0651: this .fireVirtualFileEvent(VirtualFileEvent.FILE_COPIED);
0652: if (!sNewPath.equals(this .getFilePath())) {
0653: vfOldParent.removeChild(sOldPath);
0654: vfOldParent
0655: .fireVirtualFileEvent(VirtualFileEvent.FILE_MEMBERS_CHANGED);
0656: }
0657: vfNewParent.addChild(sNewFilePath);
0658: vfNewParent
0659: .fireVirtualFileEvent(VirtualFileEvent.FILE_MEMBERS_CHANGED);
0660: }
0661:
0662: return retnStatus;
0663: }
0664:
0665: /**
0666: * Copies the file to a new path, giving the copy the same name as the current
0667: * version of the file.
0668: *
0669: * @param sNewPath Path to copy to
0670: * @return true if the method was successful
0671: */
0672: public StatusData copy(String sNewPath) {
0673: VFSStatus retnStatus = new VFSStatus();
0674: retnStatus.setMethodName(METHOD_COPY);
0675:
0676: String sOldPath = this .getFullPath();
0677: VirtualFile vfOldParent = this .m_vfs.getVirtualFile(
0678: this .getFilePath()).getResource();
0679: VirtualFile vfNewParent = this .m_vfs.getVirtualFile(sNewPath)
0680: .getResource();
0681: StatusData vfsStatus = this .m_vfs.copyVirtualFile(this
0682: .getFullPath(), sNewPath + "/" + this .getFileName());
0683: retnStatus.addStatusData(vfsStatus);
0684: if (retnStatus.isOK()) {
0685: sNewPath = sNewPath + "/" + this .getFileName();
0686: vfOldParent.removeChild(sOldPath);
0687: vfNewParent.addChild(sNewPath);
0688: this .fireVirtualFileEvent(VirtualFileEvent.FILE_COPIED);
0689: vfOldParent
0690: .fireVirtualFileEvent(VirtualFileEvent.FILE_MEMBERS_CHANGED);
0691: vfNewParent
0692: .fireVirtualFileEvent(VirtualFileEvent.FILE_MEMBERS_CHANGED);
0693: }
0694:
0695: return retnStatus;
0696: }
0697:
0698: /**
0699: * Moves the file to a new path with a new filename.
0700: *
0701: * @param sNewPath Path to move to
0702: * @param sNewFilename Filename to give the file
0703: * @return true if the methods was successful
0704: */
0705: public StatusData move(String sNewPath, String sNewFilename) {
0706: VFSStatus retnStatus = new VFSStatus();
0707: retnStatus.setMethodName(METHOD_MOVE);
0708:
0709: String sOldPath = this .getFullPath();
0710: VirtualFile vfOldParent = this .m_vfs.getVirtualFile(
0711: this .getFilePath()).getResource();
0712: VirtualFile vfNewParent = this .m_vfs.getVirtualFile(sNewPath)
0713: .getResource();
0714: StatusData vfsStatus = this .m_vfs.moveVirtualFile(this
0715: .getFullPath(), sNewPath + "/" + sNewFilename);
0716: retnStatus.addStatusData(vfsStatus);
0717: if (retnStatus.isOK()) {
0718: sNewPath = sNewPath + "/" + sNewFilename;
0719: vfOldParent.removeChild(sOldPath);
0720: vfNewParent.addChild(sNewPath);
0721: this .fireVirtualFileEvent(VirtualFileEvent.FILE_MOVED);
0722: vfOldParent
0723: .fireVirtualFileEvent(VirtualFileEvent.FILE_MEMBERS_CHANGED);
0724: vfNewParent
0725: .fireVirtualFileEvent(VirtualFileEvent.FILE_MEMBERS_CHANGED);
0726: }
0727:
0728: return retnStatus;
0729: }
0730:
0731: /**
0732: * Renames the virtual file.
0733: *
0734: * @param sNewFilename New name
0735: * @return true if the methods was successful
0736: */
0737: public StatusData rename(String sNewFilename) {
0738: VFSStatus retnStatus = new VFSStatus();
0739: retnStatus.setMethodName(METHOD_RENAME);
0740:
0741: String sOldPath = this .getFullPath();
0742: StatusData vfsStatus = this .m_vfs.moveVirtualFile(this
0743: .getFullPath(), this .m_sFilePath + "/" + sNewFilename);
0744: retnStatus.addStatusData(vfsStatus);
0745: if (retnStatus.isOK()) {
0746: String sNewPath = this .getFilePath() + "/" + sNewFilename;
0747: VirtualFile vfParent = this .m_vfs.getVirtualFile(
0748: this .getFilePath()).getResource();
0749: vfParent.removeChild(sOldPath);
0750: vfParent.addChild(sNewPath);
0751: this .fireVirtualFileEvent(VirtualFileEvent.FILE_RENAMED);
0752: vfParent
0753: .fireVirtualFileEvent(VirtualFileEvent.FILE_MEMBERS_CHANGED);
0754: }
0755:
0756: return retnStatus;
0757: }
0758:
0759: /**
0760: * Moves the file to a new path.
0761: *
0762: * @param sNewPath Path to move to
0763: * @return true if the methods was successful
0764: */
0765: public StatusData move(String sNewPath) {
0766: VFSStatus retnStatus = new VFSStatus();
0767: retnStatus.setMethodName(METHOD_MOVE);
0768:
0769: String sOldPath = this .getFullPath();
0770: VirtualFile vfOldParent = this .m_vfs.getVirtualFile(
0771: this .getFilePath()).getResource();
0772: VirtualFile vfNewParent = this .m_vfs.getVirtualFile(sNewPath)
0773: .getResource();
0774: StatusData vfsStatus = this .m_vfs.moveVirtualFile(this
0775: .getFullPath(), sNewPath + "/" + this .getFileName());
0776: retnStatus.addStatusData(vfsStatus);
0777: if (retnStatus.isOK()) {
0778: sNewPath = sNewPath + "/" + this .getFileName();
0779: vfOldParent.removeChild(sOldPath);
0780: vfNewParent.addChild(sNewPath);
0781: this .fireVirtualFileEvent(VirtualFileEvent.FILE_MOVED);
0782: vfOldParent
0783: .fireVirtualFileEvent(VirtualFileEvent.FILE_MEMBERS_CHANGED);
0784: vfNewParent
0785: .fireVirtualFileEvent(VirtualFileEvent.FILE_MEMBERS_CHANGED);
0786: }
0787:
0788: return retnStatus;
0789: }
0790:
0791: /**
0792: * Deletes the file.
0793: * @return true if the methods was successful
0794: */
0795: public StatusData delete() {
0796: VFSStatus retnStatus = new VFSStatus();
0797: retnStatus.setMethodName(METHOD_DELETE);
0798:
0799: VirtualFile vfParent = this .m_vfs.getVirtualFile(
0800: this .m_sFilePath).getResource();
0801: StatusData vfsStatus = this .m_vfs.deleteVirtualFile(this
0802: .getFullPath());
0803: retnStatus.addStatusData(vfsStatus);
0804: if (retnStatus.isOK()) {
0805: this .fireVirtualFileEvent(VirtualFileEvent.FILE_DELETED);
0806: if (vfParent != null
0807: && !((this instanceof VersionedVirtualFile) && ((VersionedVirtualFile) this )
0808: .getLiveVersionPath() != null)) {
0809: vfParent.removeChild(this .getFullPath());
0810: vfParent.refreshChildren();
0811: vfParent
0812: .fireVirtualFileEvent(VirtualFileEvent.FILE_MEMBERS_CHANGED);
0813: }
0814: }
0815:
0816: return retnStatus;
0817: }
0818:
0819: /**
0820: * Locks the file to the logged in user.
0821: * @return true if the methods was successful
0822: */
0823: public StatusData lock() {
0824: VFSStatus retnStatus = new VFSStatus();
0825: retnStatus.setMethodName(METHOD_LOCK);
0826:
0827: StatusData vfsStatus = this .m_vfs.lockVirtualFile(this
0828: .getFullPath());
0829: retnStatus.addStatusData(vfsStatus);
0830: if (retnStatus.isOK()) {
0831: this .fireVirtualFileEvent(VirtualFileEvent.FILE_LOCKED);
0832: }
0833:
0834: return retnStatus;
0835: }
0836:
0837: /**
0838: * Unlocks the file.
0839: * @return true if the methods was successful
0840: */
0841: public StatusData unlock() {
0842: VFSStatus retnStatus = new VFSStatus();
0843: retnStatus.setMethodName(METHOD_UNLOCK);
0844:
0845: StatusData vfsStatus = this .m_vfs.unlockVirtualFile(this
0846: .getFullPath());
0847: retnStatus.addStatusData(vfsStatus);
0848: if (retnStatus.isOK()) {
0849: this .fireVirtualFileEvent(VirtualFileEvent.FILE_UNLOCKED);
0850: }
0851:
0852: return retnStatus;
0853: }
0854:
0855: /**
0856: * Creates a new directory with the current one. Only works on Virtual Files that
0857: * are directories.
0858: *
0859: * @param sDirname Name to give to new directory
0860: * @return true if the methods was successful
0861: */
0862: public StatusData mkDir(String sDirname) {
0863: VFSStatus retnStatus = new VFSStatus();
0864: retnStatus.setMethodName(METHOD_MKDIR);
0865:
0866: StatusData vfsStatus = this .m_vfs.createVirtualDirectory(this
0867: .getFullPath()
0868: + "/" + sDirname);
0869: retnStatus.addStatusData(vfsStatus);
0870: if (retnStatus.isOK()) {
0871: this .refreshChildren();
0872: this
0873: .fireVirtualFileEvent(VirtualFileEvent.FILE_MEMBERS_CHANGED);
0874: }
0875:
0876: return retnStatus;
0877: }
0878:
0879: /**
0880: * Creates a new shortcut to a specified file with a specified name within
0881: * the current directory, only works on Virtual Files that are directories.
0882: *
0883: * @param sShortcutName Name to give to new shortcut
0884: * @param sFromFullPath Path that the new shortcut points to
0885: * @return true if the methods was successful
0886: */
0887: public StatusData createShortcut(String sShortcutName,
0888: String sFromFullPath) {
0889: VFSStatus retnStatus = new VFSStatus();
0890: retnStatus.setMethodName(METHOD_SHORTCUT);
0891:
0892: StatusData vfsStatus = this .m_vfs.createShortcut(sFromFullPath,
0893: this .getFullPath() + "/" + sShortcutName);
0894: retnStatus.addStatusData(vfsStatus);
0895: if (retnStatus.isOK()) {
0896: this
0897: .fireVirtualFileEvent(VirtualFileEvent.FILE_MEMBERS_CHANGED);
0898: }
0899:
0900: return retnStatus;
0901: }
0902:
0903: /**
0904: * Returns the owner of the lock on the file, if there is one.
0905: *
0906: * @return Username of the lock owner, null if there is no lock
0907: */
0908: public String getLockOwner() {
0909: return this .m_sLockOwner;
0910: }
0911:
0912: /**
0913: * Sets the owner of the lock on the file. This should be the path to
0914: * the virtual file for the principal representing the user who owns
0915: * the lock.
0916: *
0917: * @param sLockOwner Username of the lock owner
0918: */
0919: public void setLockOwner(String sLockOwner) {
0920: this .m_sLockOwner = sLockOwner;
0921: }
0922:
0923: /**
0924: * Returns the lock token for the lock on the file, if there is one.
0925: *
0926: * @return Lock token of the lock, null if there is no lock
0927: */
0928: public String getLockToken() {
0929: return this .m_sLockToken;
0930: }
0931:
0932: /**
0933: * Sets the lock token for the lock on the file.
0934: *
0935: * @param sLockToken Lock token for the lock on the file
0936: */
0937: public void setLockToken(String sLockToken) {
0938: this .m_sLockToken = sLockToken;
0939: }
0940:
0941: /**
0942: * Checks if this virtual file is locked.
0943: *
0944: * @return True if the file is locked
0945: */
0946: public boolean isLocked() {
0947: return (this .m_sLockOwner != null || this .m_sLockToken != null);
0948: }
0949:
0950: /**
0951: * Checks if this virtual file is a collection.
0952: *
0953: * @return true if this virtual file is a collection
0954: */
0955: public boolean isDirectory() {
0956: return this .m_bIsDirectory;
0957: }
0958:
0959: /**
0960: * Sets if this virtual file is a collection.
0961: *
0962: * @param bIsDirectory True to set that this virtual file is a collection
0963: */
0964: public void setIsDirectory(boolean bIsDirectory) {
0965: this .m_bIsDirectory = bIsDirectory;
0966: }
0967:
0968: /**
0969: * Returns the contents for this virtual file.
0970: *
0971: * @return Content
0972: */
0973: public byte[] getContent() {
0974: byte[] dataRetn = null;
0975:
0976: if (!this .m_bContentChanged && !this .isContentPopulated()) {
0977: this .m_content = this .m_vfs.getVirtualFileContent(this
0978: .getFullPath());
0979: }
0980:
0981: dataRetn = this .m_content;
0982:
0983: return dataRetn;
0984: }
0985:
0986: /**
0987: * Sets the content for this virtual file.
0988: *
0989: * @param bs Content
0990: */
0991: public void setContent(byte[] bs) {
0992: this .m_bContentChanged = true;
0993: m_content = bs;
0994: if (bs != null) {
0995: this
0996: .fireVirtualFileEvent(VirtualFileEvent.FILE_CONTENT_CHANGED);
0997: }
0998: }
0999:
1000: /**
1001: * Returns the name of this virtual file.
1002: *
1003: * @return Name of this virtual file
1004: */
1005: public String getFileName() {
1006: return m_sFileName;
1007: }
1008:
1009: /**
1010: * Sets the name of this virtual file.
1011: *
1012: * @param string Name for this virtual file
1013: */
1014: public void setFileName(String string) {
1015: m_sFileName = string;
1016: }
1017:
1018: /**
1019: * Returns the path to the parent collection of this virtual file.
1020: *
1021: * @return Path to parent collection
1022: */
1023: public String getFilePath() {
1024: return m_sFilePath;
1025: }
1026:
1027: /**
1028: * Sets the path to the parent collection for this virtual file.
1029: *
1030: * @param string Path to parent collection
1031: */
1032: public void setFilePath(String string) {
1033: m_sFilePath = string;
1034: }
1035:
1036: /**
1037: * Checks if this virtual file exists within the virtual file system
1038: * that this virtual file belongs to.
1039: *
1040: * @return true if this virtual file exists
1041: */
1042: public boolean exists() {
1043: return this .m_vfs.exists(this .m_sFullPath);
1044: }
1045:
1046: /**
1047: * Adds a {@link VirtualFileListener}.
1048: *
1049: * @param listener Listener to add
1050: */
1051: public void addVirtualFileListener(VirtualFileListener listener) {
1052: if (!this .m_listeners.contains(listener)) {
1053: this .m_listeners.add(listener);
1054: }
1055: }
1056:
1057: /**
1058: * Removes a {@link VirtualFileListener}.
1059: *
1060: * @param listener Listener to remove
1061: */
1062: public void removeVirtualFileListener(VirtualFileListener listener) {
1063: this .m_listeners.remove(listener);
1064: }
1065:
1066: /**
1067: * Creates and fires a {@link VirtualFileEvent} to all the listeners.
1068: *
1069: * @param sEventType Event type
1070: */
1071: public void fireVirtualFileEvent(String sEventType) {
1072: this .fireVirtualFileEvent(sEventType, EVENT_NOTHING, null);
1073: }
1074:
1075: /**
1076: * Creates and fires a {@link VirtualFileEvent} to all the listeners.
1077: *
1078: * @param sEventType Event type
1079: */
1080: public void fireVirtualFileEvent(String sEventType,
1081: int nEventAction, String sPath) {
1082:
1083: if (sEventType.equals(VirtualFileEvent.FILE_METADATA_CHANGED)) {
1084: this .m_bMetadataChanged = true;
1085: } else if (sEventType
1086: .equals(VirtualFileEvent.FILE_CONTENT_CHANGED)) {
1087: this .m_bContentChanged = true;
1088: }
1089:
1090: VirtualFileEvent vfe = new VirtualFileEvent(this .m_sFullPath,
1091: this .m_vfs, sEventType);
1092: if (nEventAction > 0) {
1093: vfe.setSubType(nEventAction);
1094: vfe.setChildPath(sPath);
1095: }
1096:
1097: Iterator itor = ((ArrayList) this .m_listeners.clone())
1098: .iterator();
1099: while (itor.hasNext()) {
1100: VirtualFileListener listener = ((VirtualFileListener) itor
1101: .next());
1102: listener.virtualFileChanged(vfe);
1103: }
1104:
1105: if (!this .isLocked()
1106: && (sEventType
1107: .equals(VirtualFileEvent.FILE_METADATA_CHANGED) || sEventType
1108: .equals(VirtualFileEvent.FILE_CONTENT_CHANGED))) {
1109: if (this .m_vfs != null) {
1110: this .lock();
1111: }
1112: }
1113: }
1114:
1115: /**
1116: * Refreshes the list of children for this virtual file.
1117: *
1118: */
1119: public void refreshChildren() {
1120: this .m_vfs.refreshChildren(this );
1121: this .m_bChildrenPopulated = false;
1122: this .m_children.clear();
1123: this
1124: .fireVirtualFileEvent(VirtualFileEvent.FILE_MEMBERS_CHANGED);
1125: }
1126:
1127: /**
1128: * Refreshes the list of children for this virtual file.
1129: *
1130: */
1131: public void refreshChildren(int nAction, String sChildPath) {
1132: this .m_vfs.refreshChildren(this );
1133: this .m_bChildrenPopulated = false;
1134: this .m_children.clear();
1135: this .fireVirtualFileEvent(
1136: VirtualFileEvent.FILE_MEMBERS_CHANGED, nAction,
1137: sChildPath);
1138: }
1139:
1140: /**
1141: * Checks to see if the logged in user will be able to lock this VirtualFile.
1142: * Will return false if the current user does not have permission,
1143: * if the VirtualFileSystem will not support locking for this VirtualFile or
1144: * if the VirtualFile is already locked by another user.
1145: *
1146: * @return true if the current user will be able to lock this VirtualFile
1147: */
1148: public boolean canLock() {
1149: // TODO Must make this correct!!!!
1150: return false;
1151: }
1152:
1153: /**
1154: * Checks to see if the logged in user will be able to unlock this VirtualFile.
1155: * Will return false if the current user does not have permission,
1156: * if the VirtualFileSystem will not support unlocking for this VirtualFile or
1157: * if the VirtualFile is locked by another user.
1158: *
1159: * @return true if the current user will be able to unlock this VirtualFile
1160: */
1161: public boolean canUnlock() {
1162: // TODO Must make this correct!!!!
1163: return false;
1164: }
1165:
1166: /**
1167: * Provides a list of the methods which might work for this VirtualFile.
1168: * This list will be dependant on the VirtualFileSystem implementation, the
1169: * server and the currently logged in user's permissions.
1170: *
1171: * @return List of Strings of method names supported for this user by this VirtualFile.
1172: */
1173: public List getAllowedMethods() {
1174: Date dt = new Date();
1175: if (this .m_dtAllowedMethodsTimeStamp == null
1176: || dt.getTime()
1177: - this .m_dtAllowedMethodsTimeStamp.getTime() > 60000 * 5/*5 mins*/) {
1178: this .m_allowedMethods.clear();
1179: this .m_vfs.fullyPopulateFileAllowedMethods(this );
1180: this .m_dtAllowedMethodsTimeStamp = dt;
1181: }
1182: return (List) this .m_allowedMethods.clone();
1183: }
1184:
1185: /**
1186: * Adds an allowed method to the list for this virtual file.
1187: *
1188: * @param sMethod Method type to add
1189: */
1190: protected void addAllowedMethods(String sMethod) {
1191: if (!this .m_allowedMethods.contains(sMethod)) {
1192: this .m_allowedMethods.add(sMethod);
1193: }
1194: }
1195:
1196: /**
1197: * Clears the list of allowed methods for this virtual file.
1198: *
1199: */
1200: protected void clearAllowedMethods() {
1201: this .m_allowedMethods = new ArrayList();
1202: }
1203:
1204: /**
1205: * Checks if this VirtualFile is under version control.
1206: *
1207: * @return true if VirtualFile is under version control
1208: */
1209: public boolean isVersionable() {
1210: return this .m_bVersionable;
1211: }
1212:
1213: /**
1214: * Sets if this VirtualFile is under version control.
1215: *
1216: * @return true to set that this VirtualFile is under version control
1217: */
1218: protected void setVersionable(boolean bVersionable) {
1219: this .m_bVersionable = bVersionable;
1220: }
1221:
1222: /**
1223: * Sets the current state of this virtual file.
1224: *
1225: * @param sState State to set
1226: */
1227: protected void setState(String sState) {
1228: this .m_sState = sState;
1229: }
1230:
1231: /**
1232: * Returns the current state of this virtual file.
1233: *
1234: * @return Current state
1235: */
1236: public String getState() {
1237: return this .m_sState;
1238: }
1239:
1240: /**
1241: * Submits any changes that have been made to this virtual file back
1242: * to the underlying file system.
1243: *
1244: * @return true if the method was successful
1245: */
1246: public StatusData sync() {
1247: VFSStatus retnStatus = new VFSStatus();
1248: retnStatus.setMethodName(METHOD_SYNC);
1249:
1250: StatusData vfsStatus = this .m_vfs.synchroniseFile(this );
1251: retnStatus.addStatusData(vfsStatus);
1252:
1253: VirtualFile vfParent = null;
1254: if (this .getState().equals(VirtualFile.STATE_PENDING)
1255: && ((VersionedVirtualFile) this ).getLiveVersionPath() != null) {
1256: VirtualFile vfLiveFile = this .m_vfs.getVirtualFile(
1257: ((VersionedVirtualFile) this ).getLiveVersionPath())
1258: .getResource();
1259: vfParent = this .m_vfs.getVirtualFile(
1260: vfLiveFile.getFilePath()).getResource();
1261: } else {
1262: vfParent = this .m_vfs.getVirtualFile(this .getFilePath())
1263: .getResource();
1264: }
1265: if (retnStatus.isOK()) {
1266: this .m_bContentChanged = false;
1267: this .m_bMetadataChanged = false;
1268: this .fireVirtualFileEvent(VirtualFileEvent.FILE_SYNCHED);
1269: }
1270: vfParent
1271: .fireVirtualFileEvent(VirtualFileEvent.FILE_MEMBERS_CHANGED);
1272: return retnStatus;
1273: }
1274:
1275: /**
1276: * Checks if this collection is able to have the order of its
1277: * children set.
1278: *
1279: * @return true if the order of children can be set
1280: */
1281: public boolean isOrderableDirectory() {
1282: return m_bOrderableDirectory;
1283: }
1284:
1285: /**
1286: * Sets that the order of the children of this collection can be set.
1287: *
1288: * @param b true if the order of the children can be set
1289: */
1290: protected void setOrderableDirectory(boolean b) {
1291: m_bOrderableDirectory = b;
1292: }
1293:
1294: /**
1295: * Clears the list of paths of children of this collection.
1296: *
1297: */
1298: protected void clearChildren() {
1299: this .m_bChildrenPopulated = false;
1300: this .m_children.clear();
1301: }
1302:
1303: /**
1304: * @param b
1305: */
1306: public void setIsVirtualDirectory(boolean bIsVirtual) {
1307: this .m_bIsVirtualDirectory = bIsVirtual;
1308: }
1309:
1310: public boolean isVirtualDirectory() {
1311: return this.m_bIsVirtualDirectory;
1312: }
1313:
1314: }
|