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.ftp.client;
020:
021: import java.io.IOException;
022: import java.net.InetAddress;
023: import java.net.URI;
024: import java.net.UnknownHostException;
025: import java.util.List;
026:
027: import org.openharmonise.commons.xml.namespace.NamespaceType;
028: import org.openharmonise.vfs.*;
029: import org.openharmonise.vfs.authentication.*;
030: import org.openharmonise.vfs.metadata.*;
031: import org.openharmonise.vfs.search.*;
032: import org.openharmonise.vfs.status.*;
033:
034: import com.enterprisedt.net.ftp.FTPClient;
035: import com.enterprisedt.net.ftp.FTPException;
036:
037: /**
038: * Represents contents of an FTP server as a virtual file system.
039: *
040: * @author Matthew Large
041: *
042: */
043: public class FTPFileSystem extends
044: org.openharmonise.vfs.AbstractVirtualFileSystem {
045:
046: private VirtualFileCache m_cache = null;
047:
048: private FTPClient m_conn = null;
049:
050: private VirtualFileSystemView m_vfView = null;
051:
052: /**
053: *
054: */
055: public FTPFileSystem(URI uri) {
056: super (uri);
057: this .setup();
058: }
059:
060: /**
061: *
062: */
063: public FTPFileSystem(URI uri, AuthInfo authInfo) {
064: super (uri, authInfo);
065: this .setup();
066: }
067:
068: /**
069: *
070: */
071: public FTPFileSystem(URI uri, AbstractAuthenticationStore authStore) {
072: super (uri, authStore);
073: this .setup();
074: }
075:
076: private void setup() {
077: InetAddress addr;
078: this .m_sInitialPath = this .m_sInitialPath.replace('\\', '/');
079:
080: try {
081: addr = InetAddress.getByName(this .getURI().getHost());
082: m_conn = new FTPClient(addr, this .getURI().getPort());
083: } catch (UnknownHostException e) {
084: e.printStackTrace();
085: } catch (IOException e) {
086: e.printStackTrace();
087: } catch (FTPException e) {
088: e.printStackTrace();
089: }
090: this .m_cache = new VirtualFileCache();
091: }
092:
093: /* (non-Javadoc)
094: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#getOptions()
095: */
096: public List getOptions() {
097: return null;
098: }
099:
100: /* (non-Javadoc)
101: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#getVirtualFile(java.lang.String)
102: */
103: public ResourceStatusWrapper getVirtualFile(String sFullPath) {
104: VirtualFile vfFile = null;
105:
106: String sRealPath = this .getInitialPath() + sFullPath;
107:
108: if (this .m_cache.hasFile(sFullPath)) {
109: vfFile = this .m_cache.getFile(sFullPath);
110: } else {
111: try {
112: vfFile = new VirtualFile(sFullPath);
113: vfFile.setVFS(this );
114: String[] sListing = this .m_conn.dir(sRealPath, true);
115: this .populateVirtualFiles(sListing, sFullPath, vfFile);
116: } catch (IOException e) {
117: e.printStackTrace();
118: } catch (FTPException e) {
119: if (e.getMessage().trim().equals(
120: "Please login with USER and PASS.")) {
121: AuthInfo auth = this .getAuthentication();
122: try {
123: this .m_conn.login(auth.getUsername(), auth
124: .getPassword());
125: } catch (IOException e1) {
126: e1.printStackTrace();
127: } catch (FTPException e1) {
128: e1.printStackTrace();
129: }
130: vfFile = this .getVirtualFile(sFullPath)
131: .getResource();
132: } else {
133: e.printStackTrace();
134: }
135: }
136: }
137:
138: if (vfFile == null) {
139: this .fireErrorEvent("FileNotFound", "The file " + sFullPath
140: + " cannot be found.");
141: }
142:
143: return new ResourceStatusWrapper(vfFile, new VFSStatus());
144: }
145:
146: private void populateVirtualFiles(String[] sListing, String sPath,
147: VirtualFile vfFile) {
148:
149: List aListing = this .getListParser(sListing).parse(sListing,
150: sPath);
151:
152: int nCount = 1;
153: for (int i = 0; i < aListing.size(); i++) {
154: if (nCount == 1) {
155: this .populateVirtualFile((FTPListItem) aListing.get(i),
156: vfFile);
157: } else if (nCount == 2) {
158: //NO-OP
159: } else {
160: VirtualFile vfChild = null;
161: String sTempPath = sPath + "/"
162: + ((FTPListItem) aListing.get(i)).getFileName();
163: if (this .m_cache.hasFile(sTempPath)) {
164: vfChild = this .m_cache.getFile(sTempPath);
165: } else {
166: vfChild = new VirtualFile(sTempPath);
167: vfChild.setVFS(this );
168: }
169: this .populateVirtualFile((FTPListItem) aListing.get(i),
170: vfChild);
171: vfFile.addChild(vfChild.getFullPath());
172: }
173:
174: nCount++;
175: }
176: if (nCount > 2) {
177: this .setFileChildrenPopulated(vfFile, true);
178: this .setFileMetadataPopulated(vfFile, true);
179: }
180:
181: }
182:
183: private void populateVirtualFile(FTPListItem item,
184: VirtualFile vfFile) {
185: vfFile.setIsDirectory(item.isDirectory());
186:
187: PropertyInstance prop = new PropertyInstance(NamespaceType.OHRM
188: .getURI(), "filesize");
189: vfFile.addProperty(prop);
190:
191: prop = new PropertyInstance(NamespaceType.OHRM.getURI(),
192: "modificationdate");
193: vfFile.addProperty(prop);
194: }
195:
196: private FTPListParseable getListParser(String[] sListing) {
197: FTPListParseable listParser = new FTPUNIXListParser();
198: return listParser;
199: }
200:
201: /* (non-Javadoc)
202: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#addVirtualFile(java.lang.String, com.simulacramedia.vfs.VirtualFile)
203: */
204: public ResourceStatusWrapper addVirtualFile(String sPath,
205: VirtualFile content) {
206: VirtualFile vfFile = null;
207:
208: String sFullPath = sPath + "/" + content.getFileName();
209:
210: sPath = this .getInitialPath() + sPath + "/"
211: + content.getFileName();
212:
213: if (this .m_cache.hasFile(sFullPath)) {
214: // NO-OP
215: } else {
216: try {
217: this .m_conn.put(content.getContent(), sPath);
218: } catch (IOException e) {
219: this
220: .fireErrorEvent(
221: "FileNotAdded",
222: "The file "
223: + sFullPath
224: + " cannot be added here, this might be because a file already exists here with the same name.");
225: e.printStackTrace();
226: } catch (FTPException e) {
227: this
228: .fireErrorEvent(
229: "FileNotAdded",
230: "The file "
231: + sFullPath
232: + " cannot be added here, this might be because a file already exists here with the same name.");
233: e.printStackTrace();
234: }
235: }
236:
237: if (vfFile == null) {
238: this
239: .fireErrorEvent(
240: "FileNotAdded",
241: "The file "
242: + sFullPath
243: + " cannot be added here, this might be because a file already exists here with the same name.");
244: }
245:
246: return new ResourceStatusWrapper(vfFile, new VFSStatus());
247: }
248:
249: /* (non-Javadoc)
250: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#moveVirtualFile(java.lang.String, java.lang.String)
251: */
252: public StatusData moveVirtualFile(String sFromFullPath,
253: String sToFullPath) {
254: VFSStatus retnStatus = new VFSStatus();
255:
256: boolean bError = false;
257:
258: String sRealFromPath = this .getInitialPath() + sFromFullPath;
259: String sRealToPath = this .getInitialPath() + sToFullPath;
260:
261: VirtualFile vfFromFile = this .getVirtualFile(sFromFullPath)
262: .getResource();
263: if (!vfFromFile.isDirectory()) {
264: byte[] content = vfFromFile.getContent();
265: try {
266: this .m_conn.put(content, sRealToPath);
267: } catch (IOException e) {
268: this
269: .fireErrorEvent(
270: "FileNotMoved",
271: "The file "
272: + sFromFullPath
273: + " cannot be moved here, this might be because a file already exists here with the same name.");
274: bError = true;
275: e.printStackTrace();
276: } catch (FTPException e) {
277: this
278: .fireErrorEvent(
279: "FileNotMoved",
280: "The file "
281: + sFromFullPath
282: + " cannot be moved here, this might be because a file already exists here with the same name.");
283: bError = true;
284: e.printStackTrace();
285: }
286:
287: if (!bError) {
288: try {
289: this .m_conn.delete(sRealFromPath);
290: } catch (IOException e1) {
291: this .fireErrorEvent("FileNotMoved",
292: "The original file " + sFromFullPath
293: + " cannot be removed.");
294: bError = true;
295: e1.printStackTrace();
296: } catch (FTPException e1) {
297: this .fireErrorEvent("FileNotMoved",
298: "The original file " + sFromFullPath
299: + " cannot be removed.");
300: bError = true;
301: e1.printStackTrace();
302: }
303: } else {
304: retnStatus.setStatusLevel(StatusData.LEVEL_ERROR);
305: retnStatus
306: .setStatusCode(StatusData.STATUS_INVALID_REQUEST);
307: }
308: }
309:
310: return retnStatus;
311: }
312:
313: /* (non-Javadoc)
314: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#copyVirtualFile(java.lang.String, java.lang.String)
315: */
316: public StatusData copyVirtualFile(String sFromFullPath,
317: String sToFullPath) {
318: VFSStatus retnStatus = new VFSStatus();
319:
320: boolean bError = false;
321:
322: String sRealFromPath = this .getInitialPath() + sFromFullPath;
323: String sRealToPath = this .getInitialPath() + sToFullPath;
324:
325: VirtualFile vfFromFile = this .getVirtualFile(sFromFullPath)
326: .getResource();
327: if (!vfFromFile.isDirectory()) {
328: byte[] content = vfFromFile.getContent();
329: try {
330: this .m_conn.put(content, sRealToPath);
331: } catch (IOException e) {
332: this
333: .fireErrorEvent(
334: "FileNotCopied",
335: "The file "
336: + sFromFullPath
337: + " cannot be copied here, this might be because a file already exists here with the same name.");
338: bError = true;
339: e.printStackTrace();
340: } catch (FTPException e) {
341: this
342: .fireErrorEvent(
343: "FileNotCopied",
344: "The file "
345: + sFromFullPath
346: + " cannot be copied here, this might be because a file already exists here with the same name.");
347: bError = true;
348: e.printStackTrace();
349: }
350: }
351:
352: if (bError) {
353: retnStatus.setStatusLevel(StatusData.LEVEL_ERROR);
354: retnStatus.setStatusCode(StatusData.STATUS_INVALID_REQUEST);
355: }
356:
357: return retnStatus;
358: }
359:
360: /* (non-Javadoc)
361: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#deleteVirtualFile(java.lang.String)
362: */
363: public StatusData deleteVirtualFile(String sFullPath) {
364: VFSStatus retnStatus = new VFSStatus();
365:
366: boolean bError = false;
367:
368: String sRealPath = this .getInitialPath() + sFullPath;
369:
370: try {
371: this .m_conn.delete(sRealPath);
372: } catch (IOException e) {
373: this .fireErrorEvent("FileNotDeleted", "The file "
374: + sFullPath + " cannot be deleted.");
375: bError = true;
376: e.printStackTrace();
377: } catch (FTPException e) {
378: this .fireErrorEvent("FileNotDeleted", "The file "
379: + sFullPath + " cannot be deleted.");
380: bError = true;
381: e.printStackTrace();
382: }
383:
384: if (bError) {
385: retnStatus.setStatusLevel(StatusData.LEVEL_ERROR);
386: retnStatus.setStatusCode(StatusData.STATUS_INVALID_REQUEST);
387: }
388:
389: return retnStatus;
390: }
391:
392: /* (non-Javadoc)
393: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#lockVirtualFile(java.lang.String)
394: */
395: public StatusData lockVirtualFile(String sFullPath) {
396: VFSStatus retnStatus = new VFSStatus();
397:
398: String sRealPath = this .getInitialPath() + sFullPath;
399: this .fireErrorEvent("FileNotLocked",
400: "This server does not support the locking of files.");
401: return retnStatus;
402: }
403:
404: /* (non-Javadoc)
405: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#unlockVirtualFile(java.lang.String)
406: */
407: public StatusData unlockVirtualFile(String sFullPath) {
408: VFSStatus retnStatus = new VFSStatus();
409:
410: String sRealPath = this .getInitialPath() + sFullPath;
411: this .fireErrorEvent("FileNotUnlocked",
412: "This server does not support the locking of files.");
413: return retnStatus;
414: }
415:
416: /* (non-Javadoc)
417: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#createVirtualDirectory(java.lang.String)
418: */
419: public StatusData createVirtualDirectory(String sFullPath) {
420: VFSStatus retnStatus = new VFSStatus();
421:
422: boolean bError = false;
423:
424: String sRealPath = this .getInitialPath() + sFullPath;
425:
426: try {
427: this .m_conn.mkdir(sRealPath);
428: } catch (IOException e) {
429: this .fireErrorEvent("DirectoryNotCreated", "The directory "
430: + sFullPath + " cannot be created.");
431: bError = true;
432: e.printStackTrace();
433: } catch (FTPException e) {
434: this .fireErrorEvent("DirectoryNotCreated", "The directory "
435: + sFullPath + " cannot be created.");
436: bError = true;
437: e.printStackTrace();
438: }
439:
440: if (bError) {
441: retnStatus.setStatusLevel(StatusData.LEVEL_ERROR);
442: retnStatus.setStatusCode(StatusData.STATUS_INVALID_REQUEST);
443: }
444:
445: return retnStatus;
446: }
447:
448: /* (non-Javadoc)
449: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#createShortcut(java.lang.String, java.lang.String)
450: */
451: public StatusData createShortcut(String sFullPath,
452: String sToFullPath) {
453: VFSStatus retnStatus = new VFSStatus();
454:
455: String sRealPath = this .getInitialPath() + sFullPath;
456: String sRealToPath = this .getInitialPath() + sToFullPath;
457: this .fireErrorEvent("ShortcutNotCreted",
458: "This server does not support shortcuts.");
459: return retnStatus;
460: }
461:
462: /* (non-Javadoc)
463: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#search(com.simulacramedia.vfs.search.Query)
464: */
465: public ResourceListStatusWrapper search(Query query) {
466: return null;
467: }
468:
469: /* (non-Javadoc)
470: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#getVirtualFileSystemView()
471: */
472: public VirtualFileSystemView getVirtualFileSystemView() {
473: if (this .m_vfView == null) {
474: this .m_vfView = new FTPFileSystemView();
475: }
476:
477: return this .m_vfView;
478: }
479:
480: /* (non-Javadoc)
481: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#getVirtualFileContent(java.lang.String)
482: */
483: public byte[] getVirtualFileContent(String sFullPath) {
484: String sRealPath = this .getInitialPath() + sFullPath;
485:
486: byte[] content = null;
487:
488: try {
489: content = this .m_conn.get(sRealPath);
490: } catch (IOException e) {
491: this .fireErrorEvent("ContentNotRetrieved",
492: "The content for " + sFullPath
493: + " could not be retrieved.");
494: e.printStackTrace();
495: } catch (FTPException e) {
496: this .fireErrorEvent("ContentNotRetrieved",
497: "The content for " + sFullPath
498: + " could not be retrieved.");
499: e.printStackTrace();
500: }
501:
502: return content;
503: }
504:
505: /* (non-Javadoc)
506: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#fullyPopulateFileMetadata(com.simulacramedia.vfs.VirtualFile)
507: */
508: protected void fullyPopulateFileMetadata(VirtualFile vfFile) {
509: // NO-OP
510: }
511:
512: /* (non-Javadoc)
513: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#fullyPopulateFileChildren(com.simulacramedia.vfs.VirtualFile)
514: */
515: protected void fullyPopulateFileChildren(VirtualFile vfFile) {
516: // NO-OP
517:
518: }
519:
520: /* (non-Javadoc)
521: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#synchroniseFile(com.simulacramedia.vfs.VirtualFile)
522: */
523: public StatusData synchroniseFile(VirtualFile vfFile) {
524: VFSStatus retnStatus = new VFSStatus();
525: return retnStatus;
526: }
527:
528: /* (non-Javadoc)
529: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#sunchroniseAllFiles()
530: */
531: public StatusData synchroniseAllFiles() {
532: VFSStatus retnStatus = new VFSStatus();
533: return retnStatus;
534: }
535:
536: /* (non-Javadoc)
537: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#exists(java.lang.String)
538: */
539: public boolean exists(String sFullPath) {
540: boolean bExists = true;
541:
542: return bExists;
543: }
544:
545: /* (non-Javadoc)
546: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#refreshChildren(com.simulacramedia.vfs.VirtualFile)
547: */
548: protected void refreshChildren(VirtualFile vfFile) {
549: }
550:
551: /* (non-Javadoc)
552: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#orderVirtualFileChildren(java.util.List, com.simulacramedia.vfs.VirtualFile)
553: */
554: public StatusData orderVirtualFileChildren(List aPaths,
555: VirtualFile vfDir) {
556: VFSStatus retnStatus = new VFSStatus();
557: return retnStatus;
558: }
559:
560: /* (non-Javadoc)
561: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#getNewValueInstance(com.simulacramedia.vfs.metadata.PropertyInstance)
562: */
563: public ValueInstance getNewValueInstance(PropertyInstance propInst) {
564: return null;
565: }
566:
567: /* (non-Javadoc)
568: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#rejectAllChanges()
569: */
570: public boolean rejectAllChanges() {
571: return false;
572: }
573:
574: /* (non-Javadoc)
575: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#fullyPopulateFileAllowedMethods(com.simulacramedia.vfs.VirtualFile)
576: */
577: protected void fullyPopulateFileAllowedMethods(VirtualFile vfFile) {
578: }
579:
580: /* (non-Javadoc)
581: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#currentUserResourcePath()
582: */
583: public String currentUserResourcePath(AuthInfo authInfo) {
584: return null;
585: }
586:
587: /* (non-Javadoc)
588: * @see com.simulacramedia.vfs.AbstractVirtualFileSystem#getChangedVirtualFiles()
589: */
590: public List getChangedVirtualFiles() {
591: return null;
592: }
593:
594: /* (non-Javadoc)
595: * @see org.openharmonise.vfs.AbstractVirtualFileSystem#getPropertyVirtualFile(java.lang.String)
596: */
597: public VirtualFile getPropertyVirtualFile(String sPropPath) {
598: return null;
599: }
600:
601: }
|