001: /*
002: * This file is part of DrFTPD, Distributed FTP Daemon.
003: *
004: * DrFTPD is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * DrFTPD is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with DrFTPD; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018: package org.drftpd;
019:
020: import java.io.FileNotFoundException;
021: import java.util.ArrayList;
022: import java.util.Collection;
023: import java.util.Hashtable;
024: import java.util.Iterator;
025: import java.util.Map;
026:
027: import net.sf.drftpd.FatalException;
028: import net.sf.drftpd.NoSFVEntryException;
029: import net.sf.drftpd.master.command.plugins.DataConnectionHandler;
030:
031: import org.apache.log4j.Logger;
032: import org.drftpd.remotefile.CaseInsensitiveHashtable;
033: import org.drftpd.remotefile.LinkedRemoteFile;
034: import org.drftpd.remotefile.LinkedRemoteFileInterface;
035:
036: /**
037: * @author mog
038: * @version $Id: SFVFile.java 1514 2006-10-16 22:18:03Z tdsoul $
039: */
040: public class SFVFile extends AbstractSFVFile {
041: private static final Logger logger = Logger
042: .getLogger(SFVFile.class);
043:
044: private transient LinkedRemoteFileInterface _companion;
045:
046: /**
047: * @param file
048: */
049: public SFVFile(LightSFVFile file) {
050: _entries = new CaseInsensitiveHashtable(file.getEntries());
051: }
052:
053: /**
054: * @deprecated use getStatus().getMissing()
055: */
056: public int filesLeft() {
057: return getStatus().getMissing();
058: }
059:
060: /**
061: * @return the number of files in the dir that are in the .sfv and aren't 0 bytes
062: * @deprecated use getStatus()
063: */
064: public int finishedFiles() {
065: return size() - getStatus().getMissing();
066:
067: // int good = 0;
068: // for (Iterator iter = getFiles().iterator(); iter.hasNext();) {
069: // LinkedRemoteFile file = (LinkedRemoteFile) iter.next();
070: // if (file.length() != 0)
071: // good++;
072: // }
073: // return good;
074: }
075:
076: public SFVStatus getStatus() {
077: int offline = 0;
078: int present = 0;
079: for (LinkedRemoteFileInterface file : getFiles()) {
080: if (file.length() != 0 && file.getXfertime() != -1) {
081: present++;
082: if (!file.isAvailable()) {
083: offline++;
084: }
085: }
086: }
087: return new SFVStatus(size(), offline, present);
088: }
089:
090: public long getChecksum(String fileName) throws NoSFVEntryException {
091: Long checksum = (Long) _entries.get(fileName);
092:
093: if (checksum == null) {
094: throw new NoSFVEntryException();
095: }
096:
097: return checksum.longValue();
098: }
099:
100: public Collection<LinkedRemoteFileInterface> getFiles() {
101: LinkedRemoteFileInterface dir;
102:
103: try {
104: dir = _companion.getParentFile();
105: } catch (FileNotFoundException e) {
106: throw new FatalException(e);
107: }
108:
109: Map sfventries = getEntries();
110: Collection<LinkedRemoteFileInterface> ret = new ArrayList<LinkedRemoteFileInterface>();
111:
112: for (Iterator iter = sfventries.entrySet().iterator(); iter
113: .hasNext();) {
114: Map.Entry element = (Map.Entry) iter.next();
115: String fileName = (String) element.getKey();
116:
117: LinkedRemoteFile file;
118:
119: try {
120: file = (LinkedRemoteFile) dir.getFile(fileName);
121: } catch (FileNotFoundException e1) {
122: continue;
123: }
124:
125: ret.add(file);
126: }
127:
128: return ret;
129: }
130:
131: /**
132: * @return The sum of the size of all files listed in this SFVFile. which
133: * have been completely uploaded.
134: * @since 2.0.4
135: */
136: public long getTotalBytesCompleted() {
137: return getTotalBytes(true);
138: }
139:
140: /**
141: * @return The sum of the size of all files listed in this SFVFile, even
142: * those which are still being transfered.
143: */
144: public long getTotalBytes() {
145: return getTotalBytes(false);
146: }
147:
148: /**
149: *
150: * @param onlyCompletedFiles -
151: * Add size of only completed files? If false, files still
152: * transferring can be added.
153: * @return The sum of the size of all files listed in this SFVFile.
154: * @since 2.0.4
155: */
156: public long getTotalBytes(boolean onlyCompletedFiles) {
157: long totalBytes = 0;
158:
159: for (Iterator iter = getFiles().iterator(); iter.hasNext();) {
160: LinkedRemoteFileInterface tmpLRFI = (LinkedRemoteFileInterface) iter
161: .next();
162: if (!onlyCompletedFiles || tmpLRFI.getXfertime() != -1) {
163: totalBytes += tmpLRFI.length();
164: }
165: }
166:
167: return totalBytes;
168: }
169:
170: public long getTotalXfertime() {
171: long totalXfertime = 0;
172:
173: for (Iterator iter = getFiles().iterator(); iter.hasNext();) {
174: totalXfertime += ((LinkedRemoteFileInterface) iter.next())
175: .getXfertime();
176: }
177:
178: return totalXfertime;
179: }
180:
181: public long getXferspeed() {
182: if ((getTotalXfertime() / 1000) == 0) {
183: return 0;
184: }
185:
186: return getTotalBytes() / (getTotalXfertime() / 1000);
187: }
188:
189: public void setCompanion(LinkedRemoteFileInterface companion) {
190: if (_companion != null) {
191: throw new IllegalStateException("Can't overwrite companion");
192: }
193:
194: _companion = companion;
195: }
196:
197: public static class SFVStatus {
198: private int _present;
199: private int _offline;
200: private int _total;
201:
202: public SFVStatus(int total, int offline, int present) {
203: _total = total;
204: _offline = offline;
205: _present = present;
206: }
207:
208: /**
209: * Returns the number of files that don't exist or are 0byte.
210: * @return the number of files that don't exist or are 0byte.
211: */
212: public int getMissing() {
213: return _total - _present;
214: }
215:
216: /**
217: * Returns the number of files that exist and are not 0 byte.
218: * @return the number of files that exist and are not 0 byte.
219: */
220: public int getPresent() {
221: return _present;
222: }
223:
224: /**
225: * Returns the number of files that are available (online).
226: *
227: * If a file is online, it is of course is also present (exists).
228: * @return the number of files that are available (present & online)
229: */
230: public int getAvailable() {
231: return _present - _offline;
232: }
233:
234: /**
235: * Returns the number of files that are offline.
236: * @return the number of files that are offline.
237: */
238: public int getOffline() {
239: return _offline;
240: }
241:
242: public boolean isFinished() {
243: return getMissing() == 0;
244: }
245: }
246: }
|