001: /*
002: * The contents of this file are subject to the
003: * Mozilla Public License Version 1.1 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
009: * See the License for the specific language governing rights and
010: * limitations under the License.
011: *
012: * The Initial Developer of the Original Code is Simulacra Media Ltd.
013: * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
014: *
015: * All Rights Reserved.
016: *
017: * Contributor(s):
018: */
019: package org.openharmonise.vfs;
020:
021: import java.net.URI;
022: import java.util.ArrayList;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.StringTokenizer;
026:
027: import org.openharmonise.vfs.authentication.*;
028: import org.openharmonise.vfs.metadata.*;
029: import org.openharmonise.vfs.search.*;
030: import org.openharmonise.vfs.status.*;
031:
032: /**
033: * This is the abstract class from which all Virtual File Systems
034: * implementations should extend.
035: *
036: * @author Matthew Large
037: * @version $Revision: 1.1 $
038: *
039: */
040: public abstract class AbstractVirtualFileSystem {
041:
042: /**
043: * Path separator used by the underlying file system, e.g. '\' for windows file system.
044: */
045: private static String PATH_SEPATATOR = "\\";
046:
047: /**
048: * Full URI for the underlying file system.
049: */
050: private URI m_uri = null;
051:
052: /**
053: * The initial path for the underlying file system, e.g. for 'http://localhost/temp/root' this would be '/temp/root/'.
054: */
055: protected String m_sInitialPath = null;
056: /**
057: * The root path segment for the underlying file system, e.g. for 'http://localhost/temp/root' this would be 'root'.
058: */
059: protected String m_sRootPathSegment = null;
060:
061: /**
062: * Authentication information to use to gain access to the underlying file system.
063: */
064: private AuthInfo m_authInfo = null;
065:
066: /**
067: * An store of authentication information from which the authentication information to use to gain access to the underlying file system.
068: */
069: private AbstractAuthenticationStore m_authStore = null;
070:
071: /**
072: * The error listeners for this virtual file system.
073: */
074: private ArrayList m_errorListeners = new ArrayList(3);
075:
076: /**
077: * @param uri URI to location file system to be connected to
078: */
079: public AbstractVirtualFileSystem(URI uri) {
080: super ();
081: m_uri = uri;
082: this .pathSetup(uri.getPath());
083: }
084:
085: /**
086: * @param uri URI to location file system to be connected to
087: * @param authInfo Authentication information
088: */
089: public AbstractVirtualFileSystem(URI uri, AuthInfo authInfo) {
090: super ();
091: m_uri = uri;
092: m_authInfo = authInfo;
093: this .pathSetup(uri.getPath());
094: }
095:
096: /**
097: * @param uri URI to location file system to be connected to
098: * @param authStore Authentication Store from which to lookup authentication information
099: */
100: public AbstractVirtualFileSystem(URI uri,
101: AbstractAuthenticationStore authStore) {
102: super ();
103: m_uri = uri;
104: m_authStore = authStore;
105: this .pathSetup(uri.getPath());
106: }
107:
108: /**
109: * Utility method to work out the parent path of passed in path
110: *
111: * @param sFullPath
112: * @return
113: */
114: protected String getParentPath(String sFullPath) {
115: return sFullPath.substring(0, sFullPath.lastIndexOf('/'));
116: }
117:
118: /**
119: * Returns the initial path for the virtual file system, e.g.
120: * if the uri for the virtual file system was http://localhost/temp/root
121: * the returned path would be '/temp/root'
122: *
123: * @return Initial path
124: */
125: public String getInitialPath() {
126: return this .m_sInitialPath;
127: }
128:
129: /**
130: * Returns the root path segment for the virtual file system, e.g.
131: * if the uri for the virtual file system was http://localhost/temp/root
132: * the returned path would be 'root'
133: *
134: * @return
135: */
136: public String getRootPathSegment() {
137: return this .m_sRootPathSegment;
138: }
139:
140: /**
141: * Internal method to take the path from the setup uri
142: * and pull out all the required information, e.g. initial path and
143: * root segment
144: *
145: * @param sPath
146: */
147: private void pathSetup(String sPath) {
148:
149: StringTokenizer sTok = new StringTokenizer(sPath, "/", false);
150:
151: String sInitialPath = "";
152: ArrayList aPathSegments = new ArrayList(5);
153:
154: while (sTok.hasMoreElements()) {
155: aPathSegments.add(sTok.nextElement());
156: }
157: Iterator itor = aPathSegments.iterator();
158: String sPathSegment = null;
159: while (itor.hasNext()) {
160: sPathSegment = (String) itor.next();
161: if (itor.hasNext()) {
162: sInitialPath = sInitialPath + "/" + sPathSegment;
163: }
164: }
165: this .m_sInitialPath = sInitialPath;
166: this .m_sRootPathSegment = sPathSegment;
167: }
168:
169: /**
170: * Returns authentication information for the current user for this file system.
171: *
172: * @return Authentication information, null if no authentication information can be found
173: */
174: public AuthInfo getAuthentication() {
175: AuthInfo authInfo = null;
176:
177: if (this .m_authInfo != null) {
178: authInfo = this .m_authInfo;
179: } else if (this .m_authStore != null) {
180: this .m_authInfo = this .m_authStore
181: .getAuthentication(this .m_uri);
182: authInfo = this .m_authInfo;
183: } else {
184: authInfo = new AuthInfo();
185: authInfo.setUsername("simulacra");
186: this .m_authInfo = authInfo;
187: }
188:
189: return authInfo;
190: }
191:
192: /**
193: * Adds an error listener to the virtual file system
194: *
195: * @param error listener to be added
196: */
197: public void addErrorListener(VirtualFileSystemErrorListener listener) {
198: this .m_errorListeners.add(listener);
199: }
200:
201: /**
202: * Creates and fires an error event to all the error listeners that
203: * have been added to this virtual file system
204: *
205: * @param sMessage Message for the error event
206: * @param sDetails Details of the error event
207: */
208: protected void fireErrorEvent(String sMessage, String sDetails) {
209: ErrorEvent error = new ErrorEvent(sMessage, sDetails);
210: Iterator itor = this .m_errorListeners.iterator();
211: while (itor.hasNext()) {
212: ((VirtualFileSystemErrorListener) itor.next()).error(error);
213: }
214: }
215:
216: /**
217: * Utility method to return a List object of path segements
218: * for a given path
219: *
220: * @param sPath Path to split into segments
221: * @param sPathSeparator The separator for the path, e.g. '/'
222: * @return List of path segment Strings
223: */
224: public static List getPathSegments(String sPath,
225: String sPathSeparator) {
226: ArrayList aSegments = new ArrayList(7);
227:
228: StringTokenizer sTok = new StringTokenizer(sPath,
229: sPathSeparator, false);
230: while (sTok.hasMoreElements()) {
231: String sTemp = (String) sTok.nextElement();
232: aSegments.add(sTemp);
233: }
234:
235: return aSegments;
236: }
237:
238: /**
239: * Returns the URI of the file system connected to
240: *
241: * @return URI of the file system
242: */
243: public URI getURI() {
244: return this .m_uri;
245: }
246:
247: /**
248: * Returns the methods that are supported by an implementation
249: *
250: * @return Comma separated list of methods that are supported by an implementation
251: */
252: public abstract List getOptions();
253:
254: /**
255: * This method will return either the Virtual File that was requested by the path
256: * or a new blank file initialised to that path
257: *
258: * @param sFullPath Full path to the requested file
259: * @return VirtualFile
260: */
261: public abstract ResourceStatusWrapper getVirtualFile(
262: String sFullPath);
263:
264: /**
265: * Adds a new virtual file to the virtual file system
266: *
267: * @param sPath Full path for the new virtual file file
268: * @param vfFile Virtual file to be added to the virtual file system
269: * @return The virtual file that was added to the virtual file system
270: */
271: public abstract ResourceStatusWrapper addVirtualFile(String sPath,
272: VirtualFile vfFile);
273:
274: /**
275: * Clears the children of a collection
276: *
277: * @param vfFile Collection to have its children cleared
278: */
279: protected void clearVirtualFileChildren(VirtualFile vfFile) {
280: vfFile.clearChildren();
281: }
282:
283: /**
284: * Sets the order of the children of a collection
285: *
286: * @param aPaths Ordered list of paths of the children of a collection
287: * @param vfDir Collection to have its children ordered
288: * @return true if the method was successful
289: */
290: public abstract StatusData orderVirtualFileChildren(List aPaths,
291: VirtualFile vfDir);
292:
293: /**
294: * Moves a Virtual File specified by the first path to the second path
295: *
296: * @param sFromFullPath Path of file to move
297: * @param sToFullPath Path to move file to
298: * @return true if the method was successful
299: */
300: public abstract StatusData moveVirtualFile(String sFromFullPath,
301: String sToFullPath);
302:
303: /**
304: * Copies a Virtual File specified by the first path to the second path
305: *
306: * @param sFromFullPath Path of file to copy
307: * @param sToFullPath Path to copy file to
308: * @return true if the method was successful
309: */
310: public abstract StatusData copyVirtualFile(String sFromFullPath,
311: String sToFullPath);
312:
313: /**
314: * Deletes a Virtual File
315: *
316: * @param sFullPath Path of file to delete
317: * @return true if the method was successful
318: */
319: public abstract StatusData deleteVirtualFile(String sFullPath);
320:
321: /**
322: * Locks a Virtual File
323: *
324: * @param sFullPath Path of file to lock
325: * @return true if the method was successful
326: */
327: public abstract StatusData lockVirtualFile(String sFullPath);
328:
329: /**
330: * Unlocks a Virtual File
331: *
332: * @param sFullPath Path of file to unlock
333: * @return true if the method was successful
334: */
335: public abstract StatusData unlockVirtualFile(String sFullPath);
336:
337: /**
338: * Creates a new Virtual Directory
339: *
340: * @param sFullPath Path of directory to be created
341: * @return true if the method was successful
342: */
343: public abstract StatusData createVirtualDirectory(String sFullPath);
344:
345: /**
346: * Creates a shortcut to a Virtual File
347: *
348: * @param sFullPath Path of shortcut to be created
349: * @param sToFullPath Path of file that the shortcut is to
350: * @return true if the method was successful
351: */
352: public abstract StatusData createShortcut(String sFullPath,
353: String sToFullPath);
354:
355: /**
356: * Performs a search of the file system using a given query, returning a List of
357: * Virtual File objects
358: *
359: * @param query Query to use as conditions on the search
360: * @return List of Virtual File objects, empty List is none where found
361: */
362: public abstract ResourceListStatusWrapper search(Query query);
363:
364: /**
365: * Checks if the given path actually exists within this virtual file
366: * system
367: *
368: * @param sFullPath Path to check
369: * @return true if the path exists within this virtual file system
370: */
371: public abstract boolean exists(String sFullPath);
372:
373: /**
374: * Access to handler for GUI elements that view the file system, e.g. file icons,
375: * display names etc
376: *
377: * @return View of file system
378: */
379: public abstract VirtualFileSystemView getVirtualFileSystemView();
380:
381: /**
382: * Return the content a path in a byte array
383: *
384: * @param sFullPath Path to get content for
385: * @return byte array of content for the path
386: */
387: public abstract byte[] getVirtualFileContent(String sFullPath);
388:
389: /**
390: * Populates all the metadata for a given virtual file, use if a
391: * virtual file was only partially populated for instance on its
392: * initial fetch
393: *
394: * @param vfFile Virtual file to have its metadata fully populated
395: */
396: protected abstract void fullyPopulateFileMetadata(VirtualFile vfFile);
397:
398: /**
399: * Populates the complete list of children for a collection, use if
400: * only the collection itself was fetched and not its children
401: *
402: * @param vfFile Collection to have its children fully populated
403: */
404: protected abstract void fullyPopulateFileChildren(VirtualFile vfFile);
405:
406: /**
407: * Submits a changed virtual file back to the virtual file system,
408: * the changes might be in the content or the metadata
409: *
410: * @param vfFile Virtual file to have its changes submitted
411: * @return true if the method was successful
412: */
413: public abstract StatusData synchroniseFile(VirtualFile vfFile);
414:
415: /**
416: * Submits all the changed virtual files in the cache back to the
417: * virtual file system, the changes might be in the content or the
418: * metadata
419: *
420: * @return true if the method was successful
421: */
422: public abstract StatusData synchroniseAllFiles();
423:
424: /**
425: * Rejects all the changes to virtual files in the cache. These
426: * virtual files will be removed from the cache to be replaced with
427: * the current versions the next time they are requested using the
428: * {@link #getVirtualFile(String)} method
429: *
430: * @return true if the method was successful
431: */
432: public abstract boolean rejectAllChanges();
433:
434: /**
435: * This method allows access to the VirtualFile {@link VirtualFile#isContentPopulated()} method.
436: *
437: * @param vfFile Virtual file to check
438: * @return true if the file's content is fully populated
439: */
440: protected boolean isFileContentPopulated(VirtualFile vfFile) {
441: return vfFile.isContentPopulated();
442: }
443:
444: /**
445: * This method allows access to the VirtualFile {@link VirtualFile#setContentPopulated(boolean)} method
446: *
447: * @param vfFile Virtual file to check
448: * @param bContentPopulated Set to true to set that the file's content is fully populated
449: */
450: protected void setFileContentPopulated(VirtualFile vfFile,
451: boolean bContentPopulated) {
452: vfFile.setContentPopulated(bContentPopulated);
453: }
454:
455: /**
456: * This method allows access to the VirtualFile {@link VirtualFile#isChildrenPopulated()} method
457: *
458: * @param vfFile Virtual file to check
459: * @return true if the file's children are fully populated
460: */
461: protected boolean isFileChildrenPopulated(VirtualFile vfFile) {
462: return vfFile.isChildrenPopulated();
463: }
464:
465: /**
466: * This method allows access to the VirtualFile {@link VirtualFile#setChildrenPopulated(boolean)} method
467: *
468: * @param vfFile Virtual file to check
469: * @param bChildrenPopulated Set to true to set that the file's children are fully populated
470: */
471: protected void setFileChildrenPopulated(VirtualFile vfFile,
472: boolean bChildrenPopulated) {
473: vfFile.setChildrenPopulated(bChildrenPopulated);
474: }
475:
476: /**
477: * This method allows access to the VirtualFile {@link VirtualFile#isMetadataPopulated()} method
478: *
479: * @param vfFile Virtual file to check
480: * @return true if the file's metadata is fully populated
481: */
482: protected boolean isFileMetadataPopulated(VirtualFile vfFile) {
483: return vfFile.isMetadataPopulated();
484: }
485:
486: /**
487: * This method allows access to the VirtualFile {@link VirtualFile#setMetadataPopulated(boolean)} method
488: *
489: * @param vfFile Virtual file to check
490: * @param bMetadataPopulated Set to true to set that the file's metadata is fully populated
491: */
492: protected void setFileMetadataPopulated(VirtualFile vfFile,
493: boolean bMetadataPopulated) {
494: vfFile.setMetadataPopulated(bMetadataPopulated);
495: }
496:
497: /**
498: * This method allows access to the VirtualFile {@link VirtualFile#setVersionable(boolean)} method
499: *
500: * @param vfFile Virtual file to check
501: * @param bVersionable Set to true to set that the file is versionable
502: */
503: protected void setFileIsVersionable(VirtualFile vfFile,
504: boolean bVersionable) {
505: vfFile.setVersionable(bVersionable);
506: }
507:
508: /**
509: * This method allows access to the VirtualFile {@link VirtualFile#setState(String)} method
510: *
511: * @param vfFile Virtual file to check
512: * @param sState Stage to set on the virtual file
513: */
514: protected void setFileState(VirtualFile vfFile, String sState) {
515: vfFile.setState(sState);
516: }
517:
518: /**
519: * This method allows access to the VirtualFile {@link VirtualFile#addAllowedMethods(String)} method
520: *
521: * @param vfFile Virtual file to check
522: * @param sMethod Allowed method to add to the virtual file
523: */
524: protected void addFileAllowedMethod(VirtualFile vfFile,
525: String sMethod) {
526: vfFile.addAllowedMethods(sMethod);
527: }
528:
529: /**
530: * Populates the allowed method list for a given virtual file
531: *
532: * @param vfFile Virtual file to have its allowed methods populated
533: */
534: protected abstract void fullyPopulateFileAllowedMethods(
535: VirtualFile vfFile);
536:
537: /**
538: * This method allows access to the VirtualFile {@link VirtualFile#clearAllowedMethods()} method
539: *
540: * @param vfFile Virtual file to check
541: */
542: protected void clearFileAllowedMethods(VirtualFile vfFile) {
543: vfFile.clearAllowedMethods();
544: }
545:
546: /**
547: * Refreshes the children of a given collection, any children that do
548: * not have current changes will be cleared from the cache and
549: * property definitions for all children will be updated if required
550: *
551: * @param vfFile Collection to have its children refreshed
552: */
553: protected abstract void refreshChildren(VirtualFile vfFile);
554:
555: /**
556: * This method allows access to the VirtualFile {@link VirtualFile#discardChanges()} method
557: *
558: * @param vfFile Path of the virtual file to check
559: */
560: public void discardFileChanges(String sPath) {
561: VirtualFile vfFile = this .getVirtualFile(sPath).getResource();
562: vfFile.discardChanges();
563: }
564:
565: /**
566: * This method allows access to the VirtualFile {@link VirtualFile#setOrderableDirectory(boolean)} method
567: * for a collection
568: *
569: * @param vfFile Path of the virtual file to check
570: * @param bOrderableDirectory True to set that the collection is orderable
571: */
572: protected void setOrderableDirectory(VirtualFile vfFile,
573: boolean bOrderableDirectory) {
574: vfFile.setOrderableDirectory(bOrderableDirectory);
575: }
576:
577: /**
578: * This method allows access to the VirtualFile {@link VirtualFile#clearAllProperties()} method
579: *
580: * @param vfFile Virtual file to check
581: */
582: protected void clearAllFileProperties(VirtualFile vfFile) {
583: vfFile.clearAllProperties();
584: }
585:
586: /**
587: * Gets a new {@link ValueInstance}, of the correct concrete type, for a given
588: * {@link PropertyInstance}
589: *
590: * @param propInst Property instance to get a new value for
591: * @return New value
592: */
593: public abstract ValueInstance getNewValueInstance(
594: PropertyInstance propInst);
595:
596: /**
597: * Returns a path to the principal's virtual file for the user in the
598: * {@link AuthInfo} object
599: *
600: * @param authInfo Authentication information to use to find the user
601: * @return Path to the principal's virtual file
602: */
603: public abstract String currentUserResourcePath(AuthInfo authInfo);
604:
605: public abstract List getChangedVirtualFiles();
606:
607: public abstract VirtualFile getPropertyVirtualFile(String sPropPath);
608:
609: }
|