0001: /*
0002: Copyright (C) 2003 Know Gate S.L. All rights reserved.
0003: C/Oña, 107 1º2 28050 Madrid (Spain)O
0004:
0005: Redistribution and use in source and binary forms, with or without
0006: modification, are permitted provided that the following conditions
0007: are met:
0008:
0009: 1. Redistributions of source code must retain the above copyright
0010: notice, this list of conditions and the following disclaimer.
0011:
0012: 2. The end-user documentation included with the redistribution,
0013: if any, must include the following acknowledgment:
0014: "This product includes software parts from hipergate
0015: (http://www.hipergate.org/)."
0016: Alternately, this acknowledgment may appear in the software itself,
0017: if and wherever such third-party acknowledgments normally appear.
0018:
0019: 3. The name hipergate must not be used to endorse or promote products
0020: derived from this software without prior written permission.
0021: Products derived from this software may not be called hipergate,
0022: nor may hipergate appear in their name, without prior written
0023: permission.
0024:
0025: This library is distributed in the hope that it will be useful,
0026: but WITHOUT ANY WARRANTY; without even the implied warranty of
0027: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
0028:
0029: You should have received a copy of hipergate License with this code;
0030: if not, visit http://www.hipergate.org or mail to info@hipergate.org
0031: */
0032:
0033: package com.knowgate.dfs;
0034:
0035: import java.lang.System;
0036: import java.io.*;
0037:
0038: import java.net.URL;
0039: import java.net.MalformedURLException;
0040: import java.net.ProtocolException;
0041:
0042: import javax.activation.DataHandler;
0043: import javax.activation.DataSource;
0044: import javax.activation.FileDataSource;
0045: import javax.activation.URLDataSource;
0046:
0047: import com.enterprisedt.net.ftp.FTPClient;
0048: import com.enterprisedt.net.ftp.FTPException;
0049: import com.enterprisedt.net.ftp.FTPTransferType;
0050:
0051: import com.knowgate.debug.DebugFile;
0052: import com.knowgate.misc.Gadgets;
0053: import com.knowgate.misc.Environment;
0054:
0055: import java.util.Properties;
0056:
0057: // ==========================================================
0058:
0059: /**
0060: * <p>Abstract FileSystem object for encasulating NFS and FTP file transfer.</p>
0061: * FileSystem can work in 100% Pure Java mode or using native operating system
0062: * atomic calls.
0063: * <p>This is an alpha state testing module.</p>
0064: * @author Sergio Montoro Ten
0065: * @version 0.7
0066: */
0067:
0068: public class FileSystem {
0069:
0070: /**
0071: * <p>Create new File System</p>
0072: * <p>Operation mode will be Pure Java by default</p>
0073: * <p>User and Password fro FTP access wil be readed from hipergate.cnf file</p>
0074: * @throws NumberFormatException If javamode property is not a positive integer number.
0075: * @throws IllegalArgumentException If javamode property is not 0, 1 or 2.
0076: */
0077:
0078: public FileSystem() throws NumberFormatException,
0079: IllegalArgumentException {
0080:
0081: try {
0082: OS = Integer.parseInt(Environment.getProfileVar(
0083: "hipergate", "javamode", String
0084: .valueOf(OS_PUREJAVA)));
0085: } catch (NumberFormatException nfe) {
0086: OS = OS_PUREJAVA;
0087: }
0088:
0089: if (OS < 0 || OS > 2)
0090: throw new IllegalArgumentException(
0091: "javamode property can only be set to 0, 1 or 2");
0092:
0093: SLASH = System.getProperty("file.separator");
0094:
0095: oRunner = null;
0096:
0097: sUsr = Environment.getProfileVar("hipergate", "fileuser",
0098: "anonymous");
0099: sPwd = Environment.getProfileVar("hipergate", "filepassword",
0100: "");
0101: }
0102:
0103: // ==========================================================
0104:
0105: /**
0106: * <p>Create new File System</p>
0107: * <p>Operation mode may be set for faster file access throught direct usage
0108: * of operating system atomic calls.</p>
0109: * <p>User and Password fro FTP access wil be readed from hipergate.cnf file</p>
0110: * @param iMode Operation Mode { OS_PUREJAVA | OS_UNIX | OS_WINDOWS }
0111: */
0112:
0113: public FileSystem(int iMode) {
0114: /* OS PAtch
0115: OS = iMode;
0116: */
0117:
0118: SLASH = System.getProperty("file.separator");
0119: oRunner = Runtime.getRuntime();
0120: sUsr = Environment.getProfileVar("hipergate", "fileuser",
0121: "anonymous");
0122: sPwd = Environment.getProfileVar("hipergate", "filepassword",
0123: "");
0124: }
0125:
0126: // ----------------------------------------------------------
0127:
0128: /**
0129: * <p>Create new File System</p>
0130: * <p>Operation mode will be Pure Java by default</p>
0131: * @param sUser User for FTP access
0132: * @param sPassword Password for FTP access
0133: */
0134:
0135: public FileSystem(String sUser, String sPassword) {
0136: OS = OS_PUREJAVA;
0137: SLASH = System.getProperty("file.separator");
0138: oRunner = Runtime.getRuntime();
0139: sUsr = sUser;
0140: sPwd = sPassword;
0141: }
0142:
0143: // ----------------------------------------------------------
0144:
0145: /**
0146: * <p>Create new File System</p>
0147: * @param iMode Operation Mode: OS_PUREJAVA or OS_UNIX or OS_WINDOWS
0148: * @param sUser User for FTP access
0149: * @param sPassword Password for FTP access
0150: */
0151:
0152: public FileSystem(int iMode, String sUser, String sPassword) {
0153: OS = iMode;
0154:
0155: SLASH = System.getProperty("file.separator");
0156: oRunner = Runtime.getRuntime();
0157: sUsr = sUser;
0158: sPwd = sPassword;
0159: }
0160:
0161: // ----------------------------------------------------------
0162:
0163: /**
0164: * Crea un FileSystem tomando los parámetros de creación necesarios
0165: * de un conjunto de propiedades.
0166: * @param oProps Conjunto de propiedades. Actualmente se usan dos:
0167: * fileuser = Nombre de Usuario a Autentificar
0168: * filepassword = Clave de Acceso del Usuario
0169: */
0170:
0171: /**
0172: *
0173: * @param oProps Properties collection.<br>
0174: * <u>Property names</u>:<br>
0175: * <b>javamode</b> : "0" (default) for Pure Java, "1" for UNIX, "2" for Windows.<br>
0176: * <b>fileuser</b> : User for FTP access (default is "anonymous").
0177: * <b>filepassword</b> : Password for FTP access (default is "").
0178: * @throws NumberFormatException If javamode property is not a positive integer number.
0179: * @throws IllegalArgumentException If javamode property is not 0, 1 or 2.
0180: */
0181: public FileSystem(Properties oProps) throws NumberFormatException,
0182: IllegalArgumentException {
0183:
0184: OS = Integer.parseInt(oProps.getProperty("javamode", "0"));
0185:
0186: if (OS < 0 || OS > 2)
0187: throw new IllegalArgumentException(
0188: "javamode property can only be set to 0, 1 or 2");
0189:
0190: SLASH = System.getProperty("file.separator");
0191:
0192: oRunner = Runtime.getRuntime();
0193:
0194: sUsr = oProps.getProperty("fileuser", "anonymous");
0195: sPwd = oProps.getProperty("filepassword", "");
0196: }
0197:
0198: // ----------------------------------------------------------
0199:
0200: /**
0201: * @param iOperatingSystem = { FileSystem.OS_PUREJAVA, FileSystem.OS_UNIX, FileSystem.OS_WINDOWS }
0202: */
0203:
0204: public void os(int iOperatingSystem) {
0205: OS = iOperatingSystem;
0206:
0207: if (OS != OS_PUREJAVA && null == oRunner)
0208: oRunner = Runtime.getRuntime();
0209: }
0210:
0211: // ----------------------------------------------------------
0212:
0213: /**
0214: * @param sUser user for FTP access
0215: */
0216:
0217: public void user(String sUser) {
0218: sUsr = sUser;
0219: }
0220:
0221: // ----------------------------------------------------------
0222:
0223: /**
0224: * @return user for FTP access.
0225: */
0226: public String user() {
0227: return sUsr;
0228: }
0229:
0230: // ----------------------------------------------------------
0231:
0232: /**
0233: * @param sPassword Password for FTP access
0234: */
0235: public void password(String sPassword) {
0236: sPwd = sPassword;
0237: }
0238:
0239: // ----------------------------------------------------------
0240:
0241: /**
0242: * @return sPassword Password for FTP access
0243: */
0244:
0245: public String password() {
0246: return sPwd;
0247: }
0248:
0249: // ----------------------------------------------------------
0250:
0251: protected String host() {
0252: return sHost;
0253: }
0254:
0255: // ----------------------------------------------------------
0256:
0257: protected String path() {
0258: return sPath;
0259: }
0260:
0261: // ----------------------------------------------------------
0262:
0263: protected String file() {
0264: return sFile;
0265: }
0266:
0267: // ----------------------------------------------------------
0268:
0269: protected void splitURI(String sURI) {
0270: String sURINoProtocol;
0271: int iHost, iPort, iPath;
0272:
0273: if (sURI.startsWith("file://")) {
0274: sURINoProtocol = sURI.substring(7);
0275: sProtocol = "file://";
0276: } else if (sURI.startsWith("ftp://")) {
0277: sURINoProtocol = sURI.substring(6);
0278: sProtocol = "ftp://";
0279: } else {
0280: sURINoProtocol = sURI;
0281: sProtocol = "";
0282: }
0283:
0284: if (sProtocol.equals("ftp://")) {
0285: iHost = sURINoProtocol.indexOf('/', 7);
0286: sHost = sURINoProtocol.substring(0, iHost);
0287: iPort = sHost.indexOf(':');
0288: if (iPort > 0) {
0289: sPort = sHost.substring(iPort + 1);
0290: sHost = sHost.substring(0, iPort);
0291: } else
0292: sPort = "";
0293:
0294: iPath = sURINoProtocol.lastIndexOf('/');
0295: sPath = sURINoProtocol.substring(iHost, iPath + 1);
0296: sFile = sURINoProtocol.substring(iPath + 1);
0297: } else if (sProtocol.equals("file://")) {
0298: sHost = "";
0299: sPort = "";
0300: iPath = sURINoProtocol.lastIndexOf('/', 8);
0301: sPath = sURINoProtocol.substring(7, iPath + 1);
0302: sFile = sURINoProtocol.substring(iPath + 1);
0303: }
0304: } // splitURI()
0305:
0306: // ---------------------------------------------------------------------------
0307:
0308: private static void copyFileNFS(String sSource, String sTarget)
0309: throws Exception {
0310: FileInputStream fis = new FileInputStream(sSource);
0311: FileOutputStream fos = new FileOutputStream(sTarget);
0312:
0313: BufferedInputStream bis = new BufferedInputStream(fis);
0314: BufferedOutputStream bos = new BufferedOutputStream(fos);
0315:
0316: byte[] buf = new byte[2048];
0317: int i = 0;
0318:
0319: while ((i = bis.read(buf)) != -1)
0320: bos.write(buf, 0, i);
0321:
0322: bis.close();
0323: bos.close();
0324: fis.close();
0325: fos.close();
0326: } // copyFileNFS()
0327:
0328: // ---------------------------------------------------------------------------
0329:
0330: private void copyFTPToFTP(String sSource, String sTarget)
0331: throws FTPException, IOException {
0332:
0333: String sSourceHost, sTargetHost, sSourcePath, sTargetPath, sSourceFile, sTargetFile, sTempName;
0334: FTPWorkerThread oReader, oWriter;
0335: FTPClient oFTPC;
0336:
0337: if (DebugFile.trace) {
0338: DebugFile.writeln("Begin FileSystem.copyFTPToFTP("
0339: + sSource + "," + sTarget + ")");
0340: DebugFile.incIdent();
0341: }
0342:
0343: splitURI(sSource);
0344: sSourceHost = sHost;
0345: sSourcePath = sPath;
0346: if (!sSourcePath.endsWith("/"))
0347: sSourcePath += "/";
0348: sSourceFile = sFile;
0349:
0350: splitURI(sTarget);
0351: sTargetHost = sHost;
0352: sTargetPath = sPath;
0353: if (!sTargetPath.endsWith("/"))
0354: sTargetPath += "/";
0355: sTargetFile = sFile;
0356:
0357: if (sSourceHost.equals(sTargetHost) && (OS != OS_PUREJAVA)) {
0358: sTempName = Gadgets.generateUUID();
0359:
0360: oFTPC = new FTPClient(sTargetHost);
0361: oFTPC.login(user(), password());
0362:
0363: if (DebugFile.trace)
0364: DebugFile.writeln("FTPClient.site(exec cp "
0365: + sSourcePath + sSourceFile + " " + sTargetPath
0366: + sTargetFile);
0367: oFTPC.rename(sSourcePath + sSourceFile, sSourcePath
0368: + sTempName);
0369: oFTPC.site("exec cp " + sSourcePath + sTempName + " "
0370: + sTargetPath + sTargetFile);
0371: oFTPC.rename(sSourcePath + sTempName, sSourcePath
0372: + sSourceFile);
0373: oFTPC.quit();
0374: } else {
0375: oReader = new FTPWorkerThread(sSourceHost, sUsr, sPwd);
0376: oWriter = new FTPWorkerThread(sTargetHost, sUsr, sPwd);
0377:
0378: oReader.get(sSourcePath + sSourceFile);
0379: oWriter.put(sTargetPath + sTargetFile);
0380:
0381: oReader.connect(oWriter.getInputPipe());
0382:
0383: if (DebugFile.trace)
0384: DebugFile.writeln("starting read pipe...");
0385:
0386: oReader.start();
0387:
0388: if (DebugFile.trace)
0389: DebugFile.writeln("starting write pipe...");
0390:
0391: oWriter.start();
0392: } // fi (sSourceHost==sTargetHost AND OS!=PUREJAVA)
0393:
0394: if (DebugFile.trace) {
0395: DebugFile.decIdent();
0396: DebugFile.writeln("End FileSystem.copyFTPToFTP()");
0397: }
0398: } // copyFTPToFTP()
0399:
0400: // ---------------------------------------------------------------------------
0401:
0402: private void copyFileToFTP(String sSource, String sTarget)
0403: throws Exception, IOException {
0404: boolean bFTPSession = false;
0405:
0406: FTPClient oFTPC = null;
0407:
0408: splitURI(sTarget);
0409:
0410: try {
0411: if (DebugFile.trace)
0412: DebugFile.writeln("new FTPClient(" + sHost + ")");
0413: oFTPC = new FTPClient(sHost);
0414: if (DebugFile.trace)
0415: DebugFile.writeln("FTPClient.login(" + sUsr + ","
0416: + sPwd + ")");
0417: oFTPC.login(sUsr, sPwd);
0418: bFTPSession = true;
0419: if (DebugFile.trace)
0420: DebugFile.writeln("FTPClient.chdir(" + sPath + ")");
0421: oFTPC.chdir(sPath);
0422: if (DebugFile.trace)
0423: DebugFile.writeln("FTPClient.put(" + sSource + ","
0424: + sFile + ",false)");
0425: oFTPC.setType(FTPTransferType.BINARY);
0426: oFTPC.put(sSource, sFile, false);
0427:
0428: } catch (FTPException ftpe) {
0429: throw new Exception(ftpe.getMessage(), ftpe.getCause());
0430: } finally {
0431: if (DebugFile.trace)
0432: DebugFile.writeln("FTPClient.quit()");
0433: if (bFTPSession)
0434: oFTPC.quit();
0435: }
0436:
0437: } // copyFileToFTP()
0438:
0439: // ---------------------------------------------------------------------------
0440:
0441: private void copyFTPToFile(String sSource, String sTarget)
0442: throws Exception, IOException {
0443:
0444: boolean bFTPSession = false;
0445:
0446: FTPClient oFTPC = null;
0447:
0448: splitURI(sSource);
0449:
0450: try {
0451: if (DebugFile.trace)
0452: DebugFile.writeln("new FTPClient(" + sHost + ")");
0453: oFTPC = new FTPClient(sHost);
0454: if (DebugFile.trace)
0455: DebugFile.writeln("FTPClient.login(" + sUsr + ","
0456: + sPwd + ")");
0457: oFTPC.login(sUsr, sPwd);
0458: bFTPSession = true;
0459: if (DebugFile.trace)
0460: DebugFile.writeln("FTPClient.chdir(" + sPath + ")");
0461: oFTPC.chdir(sPath);
0462: if (DebugFile.trace)
0463: DebugFile.writeln("FTPClient.get(" + sTarget + ","
0464: + sFile + ",false)");
0465: oFTPC.setType(FTPTransferType.BINARY);
0466: oFTPC.get(sTarget, sFile);
0467:
0468: } catch (FTPException ftpe) {
0469: throw new Exception(ftpe.getMessage(), ftpe.getCause());
0470: } finally {
0471: if (DebugFile.trace)
0472: DebugFile.writeln("FTPClient.quit()");
0473: if (bFTPSession)
0474: oFTPC.quit();
0475: }
0476:
0477: } // copyFileToFTP()
0478:
0479: // ---------------------------------------------------------------------------
0480:
0481: private static void copyHTTPToFile(String sSource, String sTarget)
0482: throws MalformedURLException, IOException {
0483:
0484: URL oUrl = new URL(sSource);
0485:
0486: FileOutputStream oTrgt = new FileOutputStream(sTarget
0487: .substring(7));
0488:
0489: DataHandler oHndlr = new DataHandler(oUrl);
0490:
0491: oHndlr.writeTo(oTrgt);
0492:
0493: oTrgt.close();
0494: } // copyHTTPToFile
0495:
0496: // ---------------------------------------------------------------------------
0497:
0498: /**
0499: * <p>Copy a file</p>
0500: * <p>This method is able to copy a file from local or network disk location
0501: * to and FTP location or viceversa.</p>
0502: * @param sSourceURI Source URI, it must have the following syntax:
0503: * protocol://[server:[port]]/path/filename
0504: * Even whe working with local files protocol must be specified, ej.
0505: * copy ("file:///tmp/upload/image.jpg", "file:///opt/storage/approved/image.jpg")
0506: * @param sTargetURI Target URI
0507: * @throws Exception
0508: * @throws IOException
0509: * @throws MalformedURLException
0510: */
0511:
0512: public boolean copy(String sSourceURI, String sTargetURI)
0513: throws MalformedURLException, IOException, Exception {
0514: // Copy a file by delegating the operation into an operating system atomic call
0515:
0516: if (DebugFile.trace) {
0517: DebugFile.writeln("Begin FileSystem.copy(" + sSourceURI
0518: + "," + sTargetURI + ")");
0519: DebugFile.incIdent();
0520: }
0521:
0522: byte verbose[] = new byte[256];
0523: boolean bRetVal;
0524: int iReaded;
0525: String sCmd;
0526: InputStream oStdOut;
0527: String sSourcePath;
0528: String sTargetPath;
0529: File oSourceFile;
0530:
0531: if (sSourceURI.startsWith("file://")
0532: && sTargetURI.startsWith("file://")) {
0533: sSourcePath = sSourceURI.substring(7);
0534: sTargetPath = sTargetURI.substring(7);
0535: oSourceFile = new File(sSourcePath);
0536:
0537: switch (OS) {
0538: case OS_UNIX:
0539: if (oSourceFile.isDirectory())
0540: sCmd = "/usr/bin/cp -r " + sSourcePath + " "
0541: + sTargetPath;
0542: else
0543: sCmd = "/usr/bin/cp \"" + sSourcePath + "\" \""
0544: + sTargetPath + "\"";
0545: break;
0546: case OS_WINDOWS:
0547: if (oSourceFile.isDirectory())
0548: sCmd = "xcopy " + sSourcePath + " " + sTargetPath
0549: + " /E /C /Q /Y";
0550: else
0551: sCmd = "copy \"" + sSourcePath + "\" \""
0552: + sTargetPath + "\"";
0553: break;
0554: default:
0555: sCmd = "";
0556: } // end switch(OS)
0557:
0558: if (sCmd.length() > 0) {
0559: if (DebugFile.trace) {
0560: DebugFile.writeln("Runtime.exec(" + sCmd + ")");
0561: oStdOut = oRunner.exec(sCmd).getInputStream();
0562: iReaded = oStdOut.read(verbose, 0, 255);
0563: oStdOut.close();
0564: if (iReaded > 0)
0565: DebugFile.writeln(new String(verbose, iReaded));
0566: } else {
0567: oRunner.exec(sCmd);
0568: bRetVal = true;
0569: }
0570: } else {
0571: if (DebugFile.trace)
0572: DebugFile.writeln("copyFileNFS(" + sSourcePath
0573: + "," + sTargetPath + ")");
0574:
0575: copyFileNFS(sSourcePath, sTargetPath);
0576: bRetVal = true;
0577: }
0578: bRetVal = true;
0579: } // fi(Source==file AND Target==file)
0580: else if (sSourceURI.startsWith("file://")
0581: && sTargetURI.startsWith("ftp://")) {
0582: sSourcePath = sSourceURI.substring(7);
0583: sTargetPath = sTargetURI.substring(6);
0584: if (DebugFile.trace)
0585: DebugFile.writeln("copyFileToFTP(" + sSourcePath + ","
0586: + sTargetURI + ")");
0587:
0588: copyFileToFTP(sSourcePath, sTargetURI);
0589: bRetVal = true;
0590: } else if (sSourceURI.startsWith("ftp://")
0591: && sTargetURI.startsWith("ftp://")) {
0592: if (DebugFile.trace)
0593: DebugFile.writeln("copyFTPToFTP(" + sSourceURI + ","
0594: + sTargetURI + ")");
0595:
0596: copyFTPToFTP(sSourceURI, sTargetURI);
0597: bRetVal = true;
0598: } else if (sSourceURI.startsWith("ftp://")
0599: && sTargetURI.startsWith("file://")) {
0600: if (DebugFile.trace)
0601: DebugFile.writeln("copyFTPToFTP(" + sSourceURI + ","
0602: + sTargetURI + ")");
0603:
0604: copyFTPToFile(sSourceURI, sTargetURI);
0605: bRetVal = true;
0606: } else if (sSourceURI.startsWith("http://")
0607: && sTargetURI.startsWith("file://")) {
0608: if (DebugFile.trace)
0609: DebugFile.writeln("copyHTTPToFile(" + sSourceURI + ","
0610: + sTargetURI + ")");
0611:
0612: copyHTTPToFile(sSourceURI, sTargetURI);
0613: bRetVal = true;
0614: } else {
0615: if (DebugFile.trace)
0616: DebugFile
0617: .writeln("ERROR: FileSystem.copy(), Source or Target protocol not recognized");
0618: bRetVal = false;
0619: throw new IOException(
0620: "FileSystem.copy(), protocol not recognized");
0621: }
0622:
0623: if (DebugFile.trace) {
0624: DebugFile.decIdent();
0625: DebugFile.writeln("End FileSystem.copy() : "
0626: + String.valueOf(bRetVal));
0627: }
0628:
0629: return bRetVal;
0630: } // copy()
0631:
0632: // ---------------------------------------------------------------------------
0633:
0634: /**
0635: * <p>Get file length</p>
0636: * Currently only local and network files length can be queried</p>
0637: * @param sFullURI File URI (protocol+path)
0638: * @return File length in bytes
0639: * @throws IOException
0640: */
0641: public int filelen(String sFullURI) throws IOException {
0642: File oFile;
0643: Long oFLng;
0644: int iFLen;
0645:
0646: if (DebugFile.trace) {
0647: DebugFile.writeln("Begin FileSystem.filelen(" + sFullURI
0648: + ")");
0649: DebugFile.incIdent();
0650: }
0651:
0652: oFile = new File(sFullURI);
0653: if (oFile.exists()) {
0654: oFLng = new Long(oFile.length());
0655: iFLen = oFLng.intValue();
0656: } else
0657: throw new IOException("File " + sFullURI
0658: + " does not exists");
0659:
0660: if (DebugFile.trace) {
0661: DebugFile.decIdent();
0662: DebugFile.writeln("End FileSystem.filelen() : "
0663: + String.valueOf(iFLen));
0664: }
0665:
0666: return iFLen;
0667: } // filelen()
0668:
0669: // ----------------------------------------------------------
0670:
0671: private static String[] listFTP(FTPClient oFTPC, String sBaseDir,
0672: char cType) throws FTPException, IOException {
0673:
0674: if (DebugFile.trace) {
0675: DebugFile.writeln("Begin FileSystem.listFTP(" + sBaseDir
0676: + "," + cType + ")");
0677: DebugFile.incIdent();
0678: }
0679:
0680: String[] aFileNames = oFTPC.dir(sBaseDir);
0681: String[] aFileAttrs = oFTPC.dir(sBaseDir, true);
0682:
0683: int iFileCount = aFileNames.length;
0684: int iAttrCount = aFileAttrs.length;
0685:
0686: boolean[] aIsDirectory = new boolean[iFileCount];
0687:
0688: for (int i = 0; i < iFileCount; i++)
0689: aIsDirectory[i] = false;
0690:
0691: String sFile;
0692: int iDirCount = 0;
0693:
0694: for (int f = 0; f < iFileCount; f++) {
0695: sFile = aFileNames[f];
0696: for (int a = 0; a < iAttrCount; a++) {
0697: if ((aFileAttrs[a].charAt(0) == cType))
0698: if (aFileAttrs[a].endsWith(sFile)) {
0699: aIsDirectory[f] = true;
0700: iDirCount++;
0701: break;
0702: } // fi
0703: } // next
0704: } // next
0705:
0706: String[] aDirNames = new String[iDirCount];
0707:
0708: iDirCount = 0;
0709:
0710: for (int d = 0; d < iFileCount; d++)
0711: if (aIsDirectory[d])
0712: aDirNames[iDirCount++] = aFileNames[d];
0713:
0714: if (DebugFile.trace) {
0715: DebugFile.decIdent();
0716: DebugFile.writeln("End FileSystem.listFTP()");
0717: }
0718:
0719: return aDirNames;
0720: } // listFTP
0721:
0722: // ----------------------------------------------------------
0723:
0724: private static String[] listDirsFTP(FTPClient oFTPC, String sBaseDir)
0725: throws FTPException, IOException {
0726: return listFTP(oFTPC, sBaseDir, 'd');
0727: }
0728:
0729: // ----------------------------------------------------------
0730:
0731: private static String[] listFilesFTP(FTPClient oFTPC,
0732: String sBaseDir) throws FTPException, IOException {
0733: return listFTP(oFTPC, sBaseDir, '-');
0734: }
0735:
0736: // ----------------------------------------------------------
0737:
0738: private static boolean isDirectoryFTP(FTPClient oFTPC,
0739: String sFilePath) throws FTPException, IOException {
0740:
0741: if (DebugFile.trace) {
0742: DebugFile.writeln("Begin FileSystem.isDirectoryFTP("
0743: + sFilePath + ")");
0744: DebugFile.incIdent();
0745: }
0746:
0747: if (sFilePath.equals("/"))
0748: return true;
0749:
0750: String sPathName, sFileName;
0751:
0752: int iSlash = sFilePath.lastIndexOf('/');
0753: if (iSlash < 1) {
0754: sPathName = "/";
0755: sFileName = sFilePath.substring(1);
0756: } else {
0757: sPathName = sFilePath.substring(0, iSlash);
0758: sFileName = sFilePath.substring(iSlash + 1);
0759: }
0760:
0761: String[] aFileAttrs = oFTPC.dir(sPathName, true);
0762: boolean bIsDir = false;
0763:
0764: int iFileCount = aFileAttrs.length;
0765:
0766: for (int d = 0; d < iFileCount; d++) {
0767: if (aFileAttrs[d].endsWith(sFileName)) {
0768: bIsDir = (aFileAttrs[d].charAt(0) == 'd');
0769: break;
0770: } // fi()
0771: } // next
0772:
0773: if (DebugFile.trace) {
0774: DebugFile.decIdent();
0775: DebugFile.writeln("End FileSystem.isDirectoryFTP() : "
0776: + String.valueOf(bIsDir));
0777: }
0778:
0779: return bIsDir;
0780: } // isDirectoryFTP
0781:
0782: // ----------------------------------------------------------
0783:
0784: /**
0785: * Remove a directory and all its subdirectories and files.
0786: * @param sFullURI Directory URI. For example: file:///tmp/upload
0787: * @return <b>true</b> if Directory was successfully deleted.
0788: * This return value should always be checked as Java functions may not return
0789: * any error but not delete a directory that is in use by another process.
0790: * @throws IOException
0791: */
0792: public boolean rmdir(String sFullURI) throws IOException {
0793: File oFile;
0794: int iReaded;
0795: String sFullPath;
0796: boolean bRetVal = false;
0797: boolean bFTPSession = false;
0798: FTPClient oFTPC = null;
0799: String sCmd = null;
0800: InputStream oStdOut;
0801: byte verbose[] = new byte[256];
0802:
0803: if (DebugFile.trace) {
0804: DebugFile.writeln("Begin FileSystem.rmdir(" + sFullURI
0805: + ")");
0806: DebugFile.incIdent();
0807: }
0808:
0809: if (sFullURI.startsWith("file://")) {
0810: sFullPath = sFullURI.substring(7);
0811: if (sFullPath.endsWith(SLASH))
0812: sFullPath = sFullPath.substring(0, sFullPath.length()
0813: - SLASH.length());
0814: oFile = new File(sFullPath);
0815:
0816: if (DebugFile.trace)
0817: DebugFile.writeln(sFullPath + " is a directory");
0818:
0819: switch (OS) {
0820: case OS_PUREJAVA:
0821: bRetVal = oFile.delete();
0822: break;
0823: case OS_UNIX:
0824: sCmd = "rm -rf \"" + sFullPath + "\"";
0825: break;
0826: case OS_WINDOWS:
0827: sCmd = "DEL /F /S /Q \"" + sFullPath + "\"";
0828: break;
0829: } // end switch()
0830:
0831: if (null != sCmd) {
0832: if (DebugFile.trace) {
0833: DebugFile.writeln("Runtime.exec(" + sCmd + ")");
0834: oStdOut = oRunner.exec(sCmd).getInputStream();
0835: iReaded = oStdOut.read(verbose, 0, 255);
0836: oStdOut.close();
0837: if (iReaded > 0) {
0838: DebugFile.writeln(new String(verbose, iReaded));
0839: bRetVal = false;
0840: } else
0841: bRetVal = true;
0842: } else {
0843: oRunner.exec(sCmd);
0844: bRetVal = true;
0845: }
0846: } // fi (sCmd)
0847:
0848: if (oFile.exists())
0849: bRetVal = false;
0850:
0851: oFile = null;
0852: }
0853:
0854: else if (sFullURI.startsWith("ftp://")) {
0855:
0856: splitURI(sFullURI);
0857:
0858: try {
0859: if (DebugFile.trace)
0860: DebugFile.writeln("new FTPClient(" + sHost + ")");
0861:
0862: oFTPC = new FTPClient(sHost);
0863:
0864: if (DebugFile.trace)
0865: DebugFile
0866: .writeln("oFTPC.login(" + sUsr + ", ...);");
0867:
0868: oFTPC.login(sUsr, sPwd);
0869:
0870: bFTPSession = true;
0871:
0872: sFullPath = Gadgets.chomp(sPath, '/') + sFile;
0873:
0874: String[] aSubDirs = listDirsFTP(oFTPC, sFullPath);
0875:
0876: for (int d = 0; d < aSubDirs.length; d++) {
0877: delete(Gadgets.chomp(sFullURI, '/') + aSubDirs[d]);
0878: }
0879:
0880: String[] aFiles = listFilesFTP(oFTPC, sFullPath);
0881:
0882: for (int f = 0; f < aFiles.length; f++) {
0883: if (DebugFile.trace)
0884: DebugFile.writeln("FTPClient.delete("
0885: + Gadgets.chomp(sPath, '/')
0886: + Gadgets.chomp(sFile, '/') + aFiles[f]
0887: + ")");
0888:
0889: oFTPC.delete(Gadgets.chomp(sPath, '/')
0890: + Gadgets.chomp(sFile, '/') + aFiles[f]);
0891: }
0892:
0893: if (DebugFile.trace)
0894: DebugFile.writeln("FTPClient.rmdir(" + sFullPath
0895: + ")");
0896:
0897: oFTPC.rmdir(sFullPath);
0898:
0899: bRetVal = true;
0900: } catch (FTPException ftpe) {
0901: bRetVal = false;
0902: throw new IOException(ftpe.getMessage());
0903: } catch (Exception xcpt) {
0904: bRetVal = false;
0905: throw new IOException(xcpt.getMessage());
0906: } finally {
0907: try {
0908: if (bFTPSession)
0909: oFTPC.quit();
0910: } catch (Exception xcpt) {
0911: }
0912: }
0913: }
0914: // fi(sFullURI.startsWith(...))
0915:
0916: if (DebugFile.trace) {
0917: DebugFile.decIdent();
0918: DebugFile.writeln("End FileSystem.rmdir() : "
0919: + String.valueOf(bRetVal));
0920: }
0921:
0922: return bRetVal;
0923: } // rmdir
0924:
0925: /**
0926: * <p>Delete o file or directory</p>
0927: * <p>Can recursively delete local or FTP directories</p>
0928: * @param sFullURI File or directory URI.
0929: * For example ftp://localhost/opt/temp/upload/logo.gif
0930: * @return <b>true</b> if File or Directory was successfully deleted.
0931: * This return value should always be checked as Java functions may not return
0932: * any error but not delete a directory or file that is in use by another process.
0933: * @throws IOException
0934: */
0935: public boolean delete(String sFullURI) throws IOException {
0936: File oFile;
0937: String sFullPath;
0938: boolean bRetVal = false;
0939: boolean bFTPSession = false;
0940: FTPClient oFTPC = null;
0941: String sCmd = null;
0942: byte verbose[] = new byte[256];
0943:
0944: if (DebugFile.trace) {
0945: DebugFile.writeln("Begin FileSystem.delete(" + sFullURI
0946: + ")");
0947: DebugFile.incIdent();
0948: switch (OS) {
0949: case OS_PUREJAVA:
0950: DebugFile.writeln("OS mode is Pure Java");
0951: break;
0952: case OS_UNIX:
0953: DebugFile.writeln("OS mode is Unix");
0954: break;
0955: case OS_WINDOWS:
0956: DebugFile.writeln("OS mode is Windows");
0957: break;
0958: }
0959: }
0960:
0961: // Codigo a ejecutar por el protocolo de ficheros locales
0962: if (sFullURI.startsWith("file://")) {
0963: sFullPath = sFullURI.substring(7);
0964: if (sFullPath.endsWith(SLASH))
0965: sFullPath = sFullPath.substring(0, sFullPath.length()
0966: - SLASH.length());
0967: oFile = new File(sFullPath);
0968:
0969: if (oFile.isFile()) {
0970: if (DebugFile.trace)
0971: DebugFile.writeln(sFullPath + " is a file");
0972: bRetVal = oFile.delete();
0973: } else {
0974: bRetVal = rmdir(sFullURI);
0975: } // fi (isFile())
0976: oFile = null;
0977: }
0978: // Codigo a ejecutar por el protocolo FTP
0979: else if (sFullURI.startsWith("ftp://")) {
0980:
0981: splitURI(sFullURI);
0982:
0983: try {
0984: if (DebugFile.trace)
0985: DebugFile.writeln("new FTPClient(" + sHost + ")");
0986:
0987: oFTPC = new FTPClient(sHost);
0988:
0989: if (DebugFile.trace)
0990: DebugFile
0991: .writeln("oFTPC.login(" + sUsr + ", ...);");
0992:
0993: oFTPC.login(sUsr, sPwd);
0994:
0995: bFTPSession = true;
0996:
0997: sFullPath = Gadgets.chomp(sPath, '/') + sFile;
0998:
0999: if (isDirectoryFTP(oFTPC, sFullPath)) {
1000: oFTPC.quit();
1001: bFTPSession = false;
1002: rmdir(sFullURI);
1003: } else {
1004: oFTPC.delete(sFullPath);
1005: }
1006:
1007: bRetVal = true;
1008: } catch (FTPException ftpe) {
1009: bRetVal = false;
1010: throw new IOException(ftpe.getMessage());
1011: } catch (Exception xcpt) {
1012: bRetVal = false;
1013: throw new IOException(xcpt.getMessage());
1014: } finally {
1015: try {
1016: if (bFTPSession)
1017: oFTPC.quit();
1018: } catch (Exception xcpt) {
1019: }
1020: }
1021: }
1022: // fi(sFullURI.startsWith(...))
1023:
1024: if (DebugFile.trace) {
1025: DebugFile.decIdent();
1026: DebugFile.writeln("End FileSystem.delete() : "
1027: + String.valueOf(bRetVal));
1028: }
1029:
1030: return bRetVal;
1031: } // delete()
1032:
1033: // ----------------------------------------------------------
1034:
1035: /**
1036: * <p>Mark an URI for deffered deletion</p>
1037: * Because web servers often cache and lock files as they are accessed,
1038: * it is sometimes not possible to delete recently accessed files inmediately.
1039: * This method just appends the given URI at the end of a plain text file
1040: * containing a list of file names. This file name list can be later used upon
1041: * Web Server re-start for purging files that could no be deleted before because
1042: * they where locked.
1043: * @param sFullURI File URI to delete, ej. file:///opt/knowgate/files/deleteme.txt
1044: * @param sDeferedFiles Local path to file containing delete list
1045: * @throws IOException
1046: */
1047:
1048: public boolean delete(String sFullURI, String sDeferedFiles)
1049: throws IOException {
1050: boolean bRetVal = delete(sFullURI);
1051: FileWriter oWrt;
1052:
1053: if (sDeferedFiles.startsWith("file://"))
1054: sDeferedFiles = sDeferedFiles.substring(7);
1055:
1056: if (!bRetVal && sFullURI.startsWith("file://")) {
1057: oWrt = new FileWriter(sDeferedFiles, true);
1058: oWrt.write("\"" + sFullURI.substring(7) + "\"\n");
1059: oWrt.close();
1060: } // fi ()
1061:
1062: return bRetVal;
1063: } // delete
1064:
1065: // ----------------------------------------------------------
1066:
1067: private boolean moveFTPToFTP(String sSourceURI, String sTargetURI)
1068: throws FTPException, IOException {
1069: boolean bRetVal = true;
1070: String sSourceHost, sTargetHost, sSourcePath, sTargetPath, sSourceFile, sTargetFile;
1071: FTPWorkerThread oReader, oWriter;
1072: FTPClient oFTPC;
1073:
1074: if (DebugFile.trace) {
1075: DebugFile.writeln("Begin FileSystem.moveFTPToFTP("
1076: + sSourceURI + "," + sTargetURI + ")");
1077: DebugFile.incIdent();
1078: }
1079:
1080: splitURI(sSourceURI);
1081: sSourceHost = sHost;
1082: sSourcePath = sPath;
1083: if (!sSourcePath.endsWith("/"))
1084: sSourcePath += "/";
1085: sSourceFile = sFile;
1086:
1087: splitURI(sTargetURI);
1088: sTargetHost = sHost;
1089: sTargetPath = sPath;
1090: if (!sTargetPath.endsWith("/"))
1091: sTargetPath += "/";
1092: sTargetFile = sFile;
1093:
1094: if (sSourceHost.equals(sTargetHost)) {
1095: if (DebugFile.trace)
1096: DebugFile.writeln("new FTPClient(" + sTargetHost + ")");
1097:
1098: oFTPC = new FTPClient(sTargetHost);
1099: oFTPC.login(user(), password());
1100:
1101: if (DebugFile.trace)
1102: DebugFile.writeln("FTPClient.rename(" + sSourcePath
1103: + sSourceFile + "," + sTargetPath + sTargetFile
1104: + ")");
1105:
1106: oFTPC.rename(sSourcePath + sSourceFile, sTargetPath
1107: + sTargetFile);
1108: oFTPC.quit();
1109: } else {
1110:
1111: oReader = new FTPWorkerThread(sSourceHost, sUsr, sPwd);
1112: oWriter = new FTPWorkerThread(sTargetHost, sUsr, sPwd);
1113:
1114: oReader.move(sSourcePath + sSourceFile);
1115: oWriter.put(sTargetPath + sTargetFile);
1116:
1117: oReader.connect(oWriter.getInputPipe());
1118:
1119: if (DebugFile.trace)
1120: DebugFile.writeln("starting read pipe...");
1121:
1122: oReader.start();
1123:
1124: if (DebugFile.trace)
1125: DebugFile.writeln("starting write pipe...");
1126:
1127: oWriter.start();
1128: }
1129:
1130: if (DebugFile.trace) {
1131: DebugFile.decIdent();
1132: DebugFile.writeln("End FileSystem.moveFTPToFTP()");
1133: }
1134: return bRetVal;
1135: } // moveFTPToFTP
1136:
1137: // ----------------------------------------------------------
1138:
1139: /**
1140: * <p>Move a file from one location to another</p>
1141: * @param sSourceURI Source URI
1142: * @param sTargetURI Target URI
1143: * @return
1144: * @throws Exception
1145: * @throws IOException
1146: */
1147:
1148: public boolean move(String sSourceURI, String sTargetURI)
1149: throws Exception, IOException {
1150: boolean bRetVal;
1151:
1152: if (sSourceURI.startsWith("ftp://")
1153: && sTargetURI.startsWith("ftp://")) {
1154: bRetVal = moveFTPToFTP(sSourceURI, sTargetURI);
1155: } else {
1156: bRetVal = copy(sSourceURI, sTargetURI);
1157: if (bRetVal)
1158: bRetVal = delete(sSourceURI);
1159: }
1160: return bRetVal;
1161: } // move
1162:
1163: // ----------------------------------------------------------
1164:
1165: /**
1166: * Rename file
1167: * @param sSourceURI Source URI (ej. "file:///tmp/files/oldfile.txt")
1168: * @param sTargetURI Target URI (ej. "file:///tmp/files/newfile.txt")
1169: * @since 2.1
1170: * @throws Exception
1171: * @throws IOException
1172: * @throws ProtocolException If source and target file does not use the same protocol, either file:// or ftp://
1173: */
1174: public boolean rename(String sSourceURI, String sTargetURI)
1175: throws Exception, IOException, ProtocolException {
1176: boolean bRetVal;
1177:
1178: if (sSourceURI.startsWith("file://")
1179: && sTargetURI.startsWith("file://")) {
1180: File oOldFile = new File(sSourceURI.substring(7));
1181: File oNewFile = new File(sTargetURI.substring(7));
1182: bRetVal = oOldFile.renameTo(oNewFile);
1183: } else if (sSourceURI.startsWith("ftp://")
1184: && sTargetURI.startsWith("ftp://")) {
1185: bRetVal = moveFTPToFTP(sSourceURI, sTargetURI);
1186: } else {
1187: throw new ProtocolException("");
1188: }
1189: return bRetVal;
1190: } // move
1191:
1192: // ----------------------------------------------------------
1193:
1194: private static void mkdirsFTP(FTPClient oFTPC, String sPath)
1195: throws IOException, FTPException {
1196: String aPath[] = Gadgets.split((sPath.endsWith("/") ? sPath
1197: .substring(0, sPath.length() - 1) : sPath), "/");
1198: String sCurrent = "/";
1199: int l = aPath.length;
1200: boolean bAlreadyExists;
1201:
1202: for (int p = 0; p <= l; p++) {
1203: try {
1204: if (DebugFile.trace)
1205: DebugFile.writeln("oFTPC.chdir(" + sCurrent + ")");
1206: oFTPC.chdir(sCurrent);
1207: bAlreadyExists = true;
1208: } catch (FTPException ftpe) {
1209: if (DebugFile.trace)
1210: DebugFile.writeln(sCurrent + " does not exist");
1211: bAlreadyExists = false;
1212: }
1213: if (!bAlreadyExists) {
1214: if (DebugFile.trace)
1215: DebugFile.writeln("oFTPC.mkdir(" + sCurrent + ")");
1216: oFTPC.mkdir(sCurrent);
1217: }
1218: if (p == l)
1219: break;
1220: sCurrent += aPath[p] + "/";
1221: } // next (p)
1222: } // mkdirsFTP
1223:
1224: // ----------------------------------------------------------
1225:
1226: /**
1227: * <p>Create a complete directory branch.</p>
1228: * @param sFullURI Full path of directory to create,
1229: * ej. file:///tmp/uploads/binaries/images
1230: * ej. ftp://ftpserver/tmp/uploads/binaries/images
1231: * @throws Exception
1232: * @throws IOException
1233: */
1234:
1235: public boolean mkdirs(String sFullURI) throws Exception,
1236: IOException {
1237: boolean bFTPSession = false;
1238: String sCmd;
1239:
1240: if (DebugFile.trace) {
1241: DebugFile.writeln("Begin FileSystem.mkdirs(" + sFullURI
1242: + ")");
1243: DebugFile.incIdent();
1244: }
1245:
1246: File oFile;
1247: FTPClient oFTPC = null;
1248: boolean bRetVal = false;
1249: String sFullPath = sFullURI.substring(7);
1250:
1251: // Assume file protocol by default
1252: if (!sFullURI.startsWith("file://")
1253: && !sFullURI.startsWith("ftp://"))
1254: sFullURI = "file://" + sFullURI;
1255:
1256: if (sFullURI.startsWith("file://")) {
1257: switch (OS) {
1258: case OS_PUREJAVA:
1259: oFile = new File(sFullPath);
1260: if (DebugFile.trace)
1261: DebugFile.writeln("File.mkdirs(" + sFullPath + ")");
1262: bRetVal = oFile.mkdirs();
1263: oFile = null;
1264: break;
1265: case OS_UNIX:
1266: if (DebugFile.trace)
1267: DebugFile.writeln("mkdir -p \"" + sFullPath + "\"");
1268: sCmd = "mkdir -p \"" + sFullPath + "\"";
1269: oRunner.exec(sCmd);
1270: break;
1271: case OS_WINDOWS:
1272: if (DebugFile.trace)
1273: DebugFile.writeln("md \"" + sFullPath + "\"");
1274: sCmd = "md \"" + sFullPath + "\"";
1275: oRunner.exec(sCmd);
1276: break;
1277: }
1278: } else if (sFullURI.startsWith("ftp://")) {
1279: if (!sFullURI.endsWith("/"))
1280: sFullURI += "/";
1281: splitURI(sFullURI);
1282:
1283: try {
1284: if (DebugFile.trace)
1285: DebugFile.writeln("new FTPClient(" + sHost + ")");
1286: oFTPC = new FTPClient(sHost);
1287:
1288: if (DebugFile.trace)
1289: DebugFile.writeln("FTPClient.login(" + sUsr + ","
1290: + sPwd + ")");
1291: oFTPC.login(sUsr, sPwd);
1292: bFTPSession = true;
1293:
1294: if (DebugFile.trace)
1295: DebugFile.writeln("FileSystem.mkdirsFTP(" + sPath
1296: + ")");
1297:
1298: mkdirsFTP(oFTPC, sPath);
1299: bRetVal = true;
1300: } catch (FTPException ftpe) {
1301: throw new IOException(ftpe.getMessage());
1302: } finally {
1303: if (bFTPSession)
1304: oFTPC.quit();
1305: }
1306: } // fi(sFullURI.startsWith(...))
1307:
1308: if (DebugFile.trace) {
1309: DebugFile.decIdent();
1310: DebugFile.writeln("End FileSystem.mkdirs() : "
1311: + String.valueOf(bRetVal));
1312: }
1313:
1314: return bRetVal;
1315: } // mkdirs()
1316:
1317: // ----------------------------------------------------------
1318:
1319: /**
1320: * <p>Convert a text file from one character set to another</p>
1321: * The input file is overwritten.
1322: * @param sFilePath File Path
1323: * @param sOldCharset Original file character set
1324: * @param sNewCharset New character set
1325: * @throws FileNotFoundException
1326: * @throws IOException
1327: * @throws UnsupportedEncodingException
1328: */
1329: public static void convert(String sFilePath, String sOldCharset,
1330: String sNewCharset) throws FileNotFoundException,
1331: IOException, UnsupportedEncodingException {
1332:
1333: if (DebugFile.trace) {
1334: DebugFile.writeln("Begin FileSystem.convert(" + sFilePath
1335: + "," + sOldCharset + "," + sNewCharset + ")");
1336: DebugFile.incIdent();
1337: }
1338:
1339: final int iBufferSize = 8192;
1340: int iReaded;
1341: char[] cBuffer = new char[iBufferSize];
1342:
1343: FileInputStream oFileStrm = new FileInputStream(sFilePath);
1344:
1345: BufferedInputStream oInStrm = new BufferedInputStream(oFileStrm);
1346:
1347: InputStreamReader oStrm = new InputStreamReader(oInStrm,
1348: sOldCharset);
1349:
1350: FileOutputStream oOutStrm = new FileOutputStream(sFilePath
1351: + ".tmp");
1352:
1353: while (true) {
1354: iReaded = oStrm.read(cBuffer, 0, iBufferSize);
1355:
1356: if (-1 == iReaded)
1357: break;
1358:
1359: oOutStrm.write(new String(cBuffer, 0, iReaded)
1360: .getBytes(sNewCharset));
1361: }
1362:
1363: oOutStrm.close();
1364:
1365: oStrm.close();
1366: oInStrm.close();
1367: oFileStrm.close();
1368:
1369: File oOld = new File(sFilePath);
1370: oOld.delete();
1371:
1372: File oNew = new File(sFilePath + ".tmp");
1373: oNew.renameTo(oOld);
1374:
1375: if (DebugFile.trace) {
1376: DebugFile.decIdent();
1377: DebugFile.writeln("End FileSystem.convert()");
1378: }
1379:
1380: } // convert
1381:
1382: // ----------------------------------------------------------
1383:
1384: private static String detectEncoding(byte[] byBuffer,
1385: String sDefault) {
1386: String sEncoding;
1387: if (byBuffer[0] == -1 && byBuffer[1] == -2)
1388: sEncoding = "UTF-16LE";
1389: else if (byBuffer[0] == -2 && byBuffer[1] == -1)
1390: sEncoding = "UTF-16BE";
1391: else if (byBuffer[0] == -17 && byBuffer[1] == -69
1392: && byBuffer[2] == -65)
1393: sEncoding = "UTF-8";
1394: else
1395: sEncoding = sDefault;
1396: return sEncoding;
1397: } // detectEncoding
1398:
1399: // ----------------------------------------------------------
1400:
1401: /**
1402: * Detect file encoding by reading its first three bytes
1403: * @param oFile File
1404: * @param sDefault String Character encoding to be returned if no clear character encoding was identified
1405: * @return String UTF-16LE, UTF-16BE or UTF-8
1406: * @throws FileNotFoundException
1407: * @throws IOException
1408: * @since 3.1
1409: */
1410: public static String detectEncoding(File oFile, String sDefault)
1411: throws FileNotFoundException, IOException {
1412: byte byBuffer[] = new byte[3];
1413: FileInputStream oInStrm = new FileInputStream(oFile);
1414: int iReaded = oInStrm.read(byBuffer, 0, 3);
1415: oInStrm.close();
1416: if (iReaded < 3)
1417: return sDefault;
1418: else
1419: return detectEncoding(byBuffer, sDefault);
1420: } // detectEncoding
1421:
1422: // ----------------------------------------------------------
1423:
1424: /**
1425: * Detect file encoding by reading its first three bytes
1426: * @param sFilePath File Path
1427: * @param sDefault String Character encoding to be returned if no clear character encoding was identified
1428: * @return String UTF-16LE, UTF-16BE or UTF-8
1429: * @throws FileNotFoundException
1430: * @throws IOException
1431: * @since 3.1
1432: */
1433: public String detectEncoding(String sFilePath, String sDefault)
1434: throws FileNotFoundException, IOException, FTPException {
1435: byte[] byBuffer = readfilebin(sFilePath);
1436: if (byBuffer == null)
1437: return sDefault;
1438: else if (byBuffer.length < 3)
1439: return sDefault;
1440: else
1441: return detectEncoding(byBuffer, sDefault);
1442: } // detectEncoding
1443:
1444: // ----------------------------------------------------------
1445:
1446: /**
1447: * <p>Read a text file and returns a character array with it</p>
1448: * Enconding is UTF-8 by default
1449: * @param sFilePath Full path of file to be readed
1450: * @return character array with full contents of file
1451: * @throws FileNotFoundException
1452: * @throws IOException
1453: * @throws OutOfMemoryError
1454: * @throws FTPException
1455: */
1456: public static char[] readfile(String sFilePath)
1457: throws FileNotFoundException, IOException,
1458: OutOfMemoryError, FTPException {
1459:
1460: if (DebugFile.trace) {
1461: DebugFile.writeln("Begin FileSystem.readfile(" + sFilePath
1462: + ")");
1463: DebugFile.incIdent();
1464: }
1465:
1466: char[] aBuffer;
1467: String sLower = sFilePath.toLowerCase();
1468:
1469: if (sLower.startsWith("file://"))
1470: sFilePath = sFilePath.substring(7);
1471:
1472: if (sLower.startsWith("http://")
1473: || sLower.startsWith("https://")
1474: || sLower.startsWith("ftp://")) {
1475: aBuffer = new FileSystem().readfilestr(sFilePath, "UTF-8")
1476: .toCharArray();
1477: } else {
1478: File oFile = new File(sFilePath);
1479:
1480: aBuffer = new char[(int) oFile.length()];
1481:
1482: FileReader oReader = new FileReader(oFile);
1483:
1484: oReader.read(aBuffer);
1485:
1486: oReader.close();
1487:
1488: oReader = null;
1489: oFile = null;
1490: }
1491:
1492: if (DebugFile.trace) {
1493: DebugFile.decIdent();
1494: DebugFile.writeln("End FileSystem.readfile() : "
1495: + String.valueOf(aBuffer.length));
1496: }
1497:
1498: return aBuffer;
1499: } // readfile
1500:
1501: // ----------------------------------------------------------
1502:
1503: /**
1504: * <p>Read a text file and returns a character array with it</p>
1505: * @param sFilePath Full path of file to be readed
1506: * @param sCharSet Encoding character set name
1507: * @return character array with full contents of file
1508: * @throws FileNotFoundException
1509: * @throws IOException
1510: * @throws OutOfMemoryError
1511: * @throws FTPException
1512: */
1513: public static char[] readfile(String sFilePath, String sCharSet)
1514: throws FileNotFoundException, IOException,
1515: OutOfMemoryError, FTPException {
1516:
1517: if (DebugFile.trace) {
1518: DebugFile.writeln("Begin FileSystem.readfile(" + sFilePath
1519: + ", charset=" + sCharSet + ")");
1520: DebugFile.incIdent();
1521: }
1522:
1523: char[] aBuffer;
1524: String sLower = sFilePath.toLowerCase();
1525:
1526: if (sLower.startsWith("file://"))
1527: sFilePath = sFilePath.substring(7);
1528:
1529: aBuffer = new FileSystem().readfilestr(sFilePath, sCharSet)
1530: .toCharArray();
1531:
1532: if (DebugFile.trace) {
1533: DebugFile.decIdent();
1534: DebugFile.writeln("End FileSystem.readfile() : "
1535: + String.valueOf(aBuffer.length));
1536: }
1537:
1538: return aBuffer;
1539: } // readfile
1540:
1541: // ----------------------------------------------------------
1542:
1543: /**
1544: * <p>Read a binary file into a byte array</p>
1545: * @param sFilePath Full path of file to be readed
1546: * @return byte array with full contents of file
1547: * @throws FileNotFoundException
1548: * @throws IOException
1549: * @throws OutOfMemoryError
1550: * @throws MalformedURLException
1551: * @throws FTPException
1552: */
1553: public byte[] readfilebin(String sFilePath)
1554: throws MalformedURLException, FTPException,
1555: FileNotFoundException, IOException, OutOfMemoryError {
1556:
1557: if (DebugFile.trace) {
1558: DebugFile.writeln("Begin FileSystem.readfilebin("
1559: + sFilePath + ")");
1560: DebugFile.incIdent();
1561: }
1562:
1563: byte[] aRetVal;
1564: String sLower = sFilePath.toLowerCase();
1565:
1566: if (sLower.startsWith("file://"))
1567: sFilePath = sFilePath.substring(7);
1568:
1569: if (sLower.startsWith("http://")
1570: || sLower.startsWith("https://")) {
1571:
1572: URL oUrl = new URL(sFilePath);
1573:
1574: ByteArrayOutputStream oStrm = new ByteArrayOutputStream();
1575:
1576: DataHandler oHndlr = new DataHandler(oUrl);
1577:
1578: oHndlr.writeTo(oStrm);
1579:
1580: aRetVal = oStrm.toByteArray();
1581:
1582: oStrm.close();
1583: } else if (sLower.startsWith("ftp://")) {
1584:
1585: FTPClient oFTPC = null;
1586: boolean bFTPSession = false;
1587:
1588: splitURI(sFilePath);
1589:
1590: try {
1591:
1592: if (DebugFile.trace)
1593: DebugFile.writeln("new FTPClient(" + sHost + ")");
1594: oFTPC = new FTPClient(sHost);
1595:
1596: if (DebugFile.trace)
1597: DebugFile.writeln("FTPClient.login(" + sUsr + ","
1598: + sPwd + ")");
1599: oFTPC.login(sUsr, sPwd);
1600:
1601: bFTPSession = true;
1602:
1603: if (DebugFile.trace)
1604: DebugFile.writeln("FTPClient.chdir(" + sPath + ")");
1605: oFTPC.chdir(sPath);
1606:
1607: ByteArrayOutputStream oStrm = new ByteArrayOutputStream();
1608:
1609: oFTPC.setType(FTPTransferType.BINARY);
1610:
1611: if (DebugFile.trace)
1612: DebugFile.writeln("FTPClient.get(" + sPath + sFile
1613: + "," + sFile + ",false)");
1614: oFTPC.get(oStrm, sFile);
1615:
1616: aRetVal = oStrm.toByteArray();
1617:
1618: oStrm.close();
1619: } catch (FTPException ftpe) {
1620: throw new FTPException(ftpe.getMessage());
1621: } finally {
1622: if (DebugFile.trace)
1623: DebugFile.writeln("FTPClient.quit()");
1624: if (bFTPSession)
1625: oFTPC.quit();
1626: }
1627:
1628: } else {
1629:
1630: File oFile = new File(sFilePath);
1631: int iFLen = (int) oFile.length();
1632:
1633: BufferedInputStream oBfStrm;
1634: FileInputStream oInStrm;
1635:
1636: if (iFLen > 0) {
1637: aRetVal = new byte[iFLen];
1638: oInStrm = new FileInputStream(oFile);
1639: oBfStrm = new BufferedInputStream(oInStrm, iFLen);
1640:
1641: int iReaded = oBfStrm.read(aRetVal, 0, iFLen);
1642:
1643: oBfStrm.close();
1644: oInStrm.close();
1645:
1646: oInStrm = null;
1647: oFile = null;
1648:
1649: } else
1650: aRetVal = null;
1651: }
1652:
1653: if (DebugFile.trace) {
1654: DebugFile.decIdent();
1655: DebugFile.writeln("End FileSystem.readfilebin()");
1656: }
1657:
1658: return aRetVal;
1659: } // readfilebin
1660:
1661: // ----------------------------------------------------------
1662:
1663: /**
1664: * <p>Read a text file into a String</p>
1665: * @param sFilePath Full path of file to be readed
1666: * @param sEncoding Text Encoding for file {UTF-8, ISO-8859-1, ...}<BR>
1667: * if <b>null</b> then if first two bytes of file are FF FE then UTF-8 will be assumed<BR>
1668: * else ISO-8859-1 will be assumed.
1669: * @return String with full contents of file
1670: * @throws FileNotFoundException
1671: * @throws IOException
1672: * @throws OutOfMemoryError
1673: * @throws MalformedURLException
1674: * @throws FTPException
1675: */
1676: public String readfilestr(String sFilePath, String sEncoding)
1677: throws MalformedURLException, FTPException,
1678: FileNotFoundException, IOException, OutOfMemoryError {
1679:
1680: if (DebugFile.trace) {
1681: DebugFile.writeln("Begin FileSystem.readfilestr("
1682: + sFilePath + "," + sEncoding + ")");
1683: DebugFile.incIdent();
1684: }
1685:
1686: String sRetVal;
1687: String sLower = sFilePath.toLowerCase();
1688:
1689: if (sLower.startsWith("file://"))
1690: sFilePath = sFilePath.substring(7);
1691:
1692: if (sLower.startsWith("http://")
1693: || sLower.startsWith("https://")) {
1694:
1695: URL oUrl = new URL(sFilePath);
1696:
1697: ByteArrayOutputStream oStrm = new ByteArrayOutputStream();
1698:
1699: DataHandler oHndlr = new DataHandler(oUrl);
1700:
1701: oHndlr.writeTo(oStrm);
1702:
1703: sRetVal = oStrm.toString(sEncoding);
1704:
1705: oStrm.close();
1706: } else if (sLower.startsWith("ftp://")) {
1707:
1708: FTPClient oFTPC = null;
1709: boolean bFTPSession = false;
1710:
1711: splitURI(sFilePath);
1712:
1713: try {
1714:
1715: if (DebugFile.trace)
1716: DebugFile.writeln("new FTPClient(" + sHost + ")");
1717: oFTPC = new FTPClient(sHost);
1718:
1719: if (DebugFile.trace)
1720: DebugFile.writeln("FTPClient.login(" + sUsr + ","
1721: + sPwd + ")");
1722: oFTPC.login(sUsr, sPwd);
1723:
1724: bFTPSession = true;
1725:
1726: if (DebugFile.trace)
1727: DebugFile.writeln("FTPClient.chdir(" + sPath + ")");
1728: oFTPC.chdir(sPath);
1729:
1730: ByteArrayOutputStream oStrm = new ByteArrayOutputStream();
1731:
1732: oFTPC.setType(FTPTransferType.BINARY);
1733:
1734: if (DebugFile.trace)
1735: DebugFile.writeln("FTPClient.get(" + sPath + sFile
1736: + "," + sFile + ",false)");
1737: oFTPC.get(oStrm, sFile);
1738:
1739: sRetVal = oStrm.toString(sEncoding);
1740:
1741: oStrm.close();
1742: } catch (FTPException ftpe) {
1743: throw new FTPException(ftpe.getMessage());
1744: } finally {
1745: if (DebugFile.trace)
1746: DebugFile.writeln("FTPClient.quit()");
1747: try {
1748: if (bFTPSession)
1749: oFTPC.quit();
1750: } catch (Exception ignore) {
1751: }
1752: }
1753: } else {
1754:
1755: File oFile = new File(sFilePath);
1756: int iFLen = (int) oFile.length();
1757: if (iFLen > 0) {
1758: byte byBuffer[] = new byte[3];
1759: char aBuffer[] = new char[iFLen];
1760: StringBuffer oBuffer = new StringBuffer(iFLen);
1761: BufferedInputStream oBfStrm;
1762: FileInputStream oInStrm;
1763: InputStreamReader oReader;
1764:
1765: if (sEncoding == null) {
1766: oInStrm = new FileInputStream(oFile);
1767: oBfStrm = new BufferedInputStream(oInStrm, iFLen);
1768:
1769: int iReaded = oBfStrm.read(byBuffer, 0, 3);
1770:
1771: if (iReaded > 2)
1772: sEncoding = detectEncoding(byBuffer,
1773: "ISO-8859-1");
1774: else
1775: sEncoding = "ISO-8859-1";
1776:
1777: if (DebugFile.trace)
1778: DebugFile.writeln("encoding is " + sEncoding);
1779:
1780: oBfStrm.close();
1781: oInStrm.close();
1782: } // fi
1783:
1784: oInStrm = new FileInputStream(oFile);
1785: oBfStrm = new BufferedInputStream(oInStrm, iFLen);
1786:
1787: oReader = new InputStreamReader(oBfStrm, sEncoding);
1788:
1789: int iReaded = oReader.read(aBuffer, 0, iFLen);
1790:
1791: // Skip FF FE character mark for Unidode files
1792: int iSkip = ((int) aBuffer[0] == 65279
1793: || (int) aBuffer[0] == 65534 ? 1 : 0);
1794:
1795: oBuffer.append(aBuffer, iSkip, iReaded - iSkip);
1796:
1797: aBuffer = null;
1798:
1799: oReader.close();
1800: oBfStrm.close();
1801: oInStrm.close();
1802:
1803: oReader = null;
1804: oInStrm = null;
1805: oFile = null;
1806:
1807: sRetVal = oBuffer.toString();
1808: } else
1809: sRetVal = "";
1810: } // fi (iFLen>0)
1811:
1812: if (DebugFile.trace) {
1813: DebugFile.decIdent();
1814: DebugFile.writeln("End FileSystem.readfilestr() : "
1815: + String.valueOf(sRetVal.length()));
1816: }
1817:
1818: return sRetVal;
1819: } // readfilestr
1820:
1821: // ----------------------------------------------------------
1822:
1823: /**
1824: * Write a String to a text file using given encoding
1825: * @param sFilePath Full file path. For example "file:///tmp/myfile.txt" or "ftp://localhost:21/tmp/myfile.txt"
1826: * @param sText String to be written
1827: * @param sEncoding Encoding to be used
1828: * see <a href="http://java.sun.com/j2se/1.4.2/docs/guide/intl/encoding.doc.html">Java Supported Encodings</a>
1829: * @throws IOException
1830: * @throws OutOfMemoryError
1831: */
1832: public void writefilestr(String sFilePath, String sText,
1833: String sEncoding) throws IOException, OutOfMemoryError {
1834:
1835: if (DebugFile.trace) {
1836: DebugFile.writeln("Begin FileSystem.writefilestr("
1837: + sFilePath + ", ..., " + sEncoding + ")");
1838: DebugFile.incIdent();
1839: }
1840:
1841: String sLower = sFilePath.toLowerCase();
1842:
1843: if (sLower.startsWith("file://"))
1844: sFilePath = sFilePath.substring(7);
1845:
1846: if (sLower.startsWith("ftp://")) {
1847:
1848: FTPClient oFTPC = null;
1849: boolean bFTPSession = false;
1850:
1851: splitURI(sFilePath);
1852:
1853: try {
1854:
1855: if (DebugFile.trace)
1856: DebugFile.writeln("new FTPClient(" + sHost + ")");
1857: oFTPC = new FTPClient(sHost);
1858:
1859: if (DebugFile.trace)
1860: DebugFile.writeln("FTPClient.login(" + sUsr + ","
1861: + sPwd + ")");
1862: oFTPC.login(sUsr, sPwd);
1863:
1864: bFTPSession = true;
1865:
1866: if (DebugFile.trace)
1867: DebugFile.writeln("FTPClient.chdir(" + sPath + ")");
1868: oFTPC.chdir(sPath);
1869:
1870: oFTPC.setType(FTPTransferType.BINARY);
1871: if (DebugFile.trace)
1872: DebugFile.writeln("FTPClient.put(byte[], " + sFile
1873: + ")");
1874: oFTPC.put(sText.getBytes(sEncoding), sFile);
1875: } catch (FTPException ftpe) {
1876: throw new IOException(ftpe.getMessage());
1877: } finally {
1878: if (DebugFile.trace)
1879: DebugFile.writeln("FTPClient.quit()");
1880: try {
1881: if (bFTPSession)
1882: oFTPC.quit();
1883: } catch (Exception ignore) {
1884: }
1885: }
1886: } else {
1887: FileOutputStream oOutStrm = new FileOutputStream(sFilePath);
1888:
1889: if (sText.length() > 0) {
1890: BufferedOutputStream oBFStrm = new BufferedOutputStream(
1891: oOutStrm, sText.length());
1892: OutputStreamWriter oWriter = new OutputStreamWriter(
1893: oBFStrm, sEncoding);
1894: oWriter.write(sText);
1895: oWriter.close();
1896: oBFStrm.close();
1897: } // fi (sText!="")
1898:
1899: oOutStrm.close();
1900: }
1901: if (DebugFile.trace) {
1902: DebugFile.decIdent();
1903: DebugFile.writeln("End FileSystem.writefilestr()");
1904: }
1905: } // writefilestr
1906:
1907: // ----------------------------------------------------------
1908:
1909: /**
1910: * Write a byte array to a text file
1911: * @param sFilePath Full file path. For example "file:///tmp/myfile.bin" or "ftp://localhost:21/tmp/myfile.bin"
1912: * @param aBytes Bytes to be written
1913: * @throws IOException
1914: * @since 3.0
1915: */
1916: public void writefilebin(String sFilePath, byte[] aBytes)
1917: throws IOException {
1918:
1919: if (DebugFile.trace) {
1920: DebugFile.writeln("Begin FileSystem.writefilebin("
1921: + sFilePath + ", ...)");
1922: DebugFile.incIdent();
1923: }
1924:
1925: String sLower = sFilePath.toLowerCase();
1926:
1927: if (sLower.startsWith("file://"))
1928: sFilePath = sFilePath.substring(7);
1929:
1930: if (sLower.startsWith("ftp://")) {
1931:
1932: FTPClient oFTPC = null;
1933: boolean bFTPSession = false;
1934:
1935: splitURI(sFilePath);
1936:
1937: try {
1938:
1939: if (DebugFile.trace)
1940: DebugFile.writeln("new FTPClient(" + sHost + ")");
1941: oFTPC = new FTPClient(sHost);
1942:
1943: if (DebugFile.trace)
1944: DebugFile.writeln("FTPClient.login(" + sUsr + ","
1945: + sPwd + ")");
1946: oFTPC.login(sUsr, sPwd);
1947:
1948: bFTPSession = true;
1949:
1950: if (DebugFile.trace)
1951: DebugFile.writeln("FTPClient.chdir(" + sPath + ")");
1952: oFTPC.chdir(sPath);
1953:
1954: oFTPC.setType(FTPTransferType.BINARY);
1955: if (DebugFile.trace)
1956: DebugFile.writeln("FTPClient.put(byte[], " + sFile
1957: + ")");
1958: oFTPC.put(aBytes, sFile);
1959: } catch (FTPException ftpe) {
1960: throw new IOException(ftpe.getMessage());
1961: } finally {
1962: if (DebugFile.trace)
1963: DebugFile.writeln("FTPClient.quit()");
1964: try {
1965: if (bFTPSession)
1966: oFTPC.quit();
1967: } catch (Exception ignore) {
1968: }
1969: }
1970: } else {
1971: FileOutputStream oOutStrm = new FileOutputStream(sFilePath);
1972: oOutStrm.write(aBytes);
1973: oOutStrm.close();
1974: }
1975: if (DebugFile.trace) {
1976: DebugFile.decIdent();
1977: DebugFile.writeln("End FileSystem.writefilebin()");
1978: }
1979: } // writefilebin
1980:
1981: // ----------------------------------------------------------
1982:
1983: // ******************
1984: // Private variables
1985:
1986: private int OS;
1987: protected String SLASH;
1988: private Runtime oRunner;
1989: private String sUsr;
1990: private String sPwd;
1991: private String sProtocol;
1992: private String sHost;
1993: private String sPort;
1994: private String sPath;
1995: private String sFile;
1996:
1997: // ******************
1998: // Static values
1999:
2000: public static final int OS_PUREJAVA = 0;
2001: public static final int OS_UNIX = 1;
2002: public static final int OS_WINDOWS = 2;
2003: }
|