001: /*
002: * This file is part of DrFTPD, Distributed FTP Daemon.
003: *
004: * DrFTPD is free software; you can redistribute it and/or modify it under the
005: * terms of the GNU General Public License as published by the Free Software
006: * Foundation; either version 2 of the License, or (at your option) any later
007: * version.
008: *
009: * DrFTPD is distributed in the hope that it will be useful, but WITHOUT ANY
010: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
011: * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
012: *
013: * You should have received a copy of the GNU General Public License along with
014: * DrFTPD; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
015: * Suite 330, Boston, MA 02111-1307 USA
016: */
017: package org.drftpd.plugins;
018:
019: import java.io.FileInputStream;
020: import java.io.IOException;
021: import java.lang.reflect.Constructor;
022: import java.util.Collection;
023: import java.util.Collections;
024: import java.util.HashSet;
025: import java.util.Iterator;
026: import java.util.Properties;
027: import java.util.TimerTask;
028:
029: import net.sf.drftpd.event.Event;
030: import net.sf.drftpd.event.FtpListener;
031:
032: import org.apache.log4j.Logger;
033: import org.drftpd.GlobalContext;
034: import org.drftpd.PropertyHelper;
035: import org.drftpd.mirroring.ArchiveHandler;
036: import org.drftpd.mirroring.ArchiveType;
037: import org.drftpd.mirroring.DuplicateArchiveException;
038: import org.drftpd.sections.SectionInterface;
039:
040: /**
041: * @author zubov
042: * @version $Id: Archive.java 1513 2006-10-13 22:41:08Z tdsoul $
043: * This addon needs a little reworking, consider it and its
044: * related packages unstable
045: */
046: public class Archive extends FtpListener {
047: private static final Logger logger = Logger
048: .getLogger(Archive.class);
049: private Properties _props;
050: private long _cycleTime;
051: private boolean _isStopped = false;
052: private HashSet<ArchiveHandler> _archiveHandlers = new HashSet<ArchiveHandler>();
053: private TimerTask _runHandler = null;
054:
055: public Archive() {
056: logger.info("Archive plugin loaded successfully");
057: }
058:
059: public Properties getProperties() {
060: return _props;
061: }
062:
063: public void actionPerformed(Event event) {
064: if (event.getCommand().equals("RELOAD")) {
065: reload();
066: return;
067: }
068: }
069:
070: /**
071: * @return the correct ArchiveType for the @section - it will return null if that section does not have an archiveType loaded for it
072: */
073: public ArchiveType getArchiveType(SectionInterface section) {
074: ArchiveType archiveType = null;
075: String name = null;
076:
077: try {
078: name = PropertyHelper.getProperty(_props, section.getName()
079: + ".archiveType");
080: } catch (NullPointerException e) {
081: return null; // excluded, not setup
082: }
083:
084: Constructor constructor = null;
085: Class[] classParams = { Archive.class, SectionInterface.class,
086: Properties.class };
087: Object[] objectParams = { this , section, _props };
088: try {
089: constructor = Class.forName(
090: "org.drftpd.mirroring.archivetypes." + name)
091: .getConstructor(classParams);
092: archiveType = (ArchiveType) constructor
093: .newInstance(objectParams);
094: } catch (Exception e2) {
095: logger.error("Unable to load ArchiveType for section "
096: + section.getName(), e2);
097: }
098:
099: return archiveType;
100: }
101:
102: /**
103: * Returns the getCycleTime setting
104: */
105: public long getCycleTime() {
106: return _cycleTime;
107: }
108:
109: public void init(GlobalContext gctx) {
110: super .init(gctx);
111: reload();
112: }
113:
114: public void reload() {
115: _props = new Properties();
116: FileInputStream fis = null;
117:
118: try {
119: fis = new FileInputStream("conf/archive.conf");
120: _props.load(fis);
121: } catch (IOException e) {
122: throw new RuntimeException(
123: "conf/archive.conf is missing, cannot continue", e);
124: } finally {
125: if (fis != null) {
126: try {
127: fis.close();
128: } catch (IOException e) {
129: logger
130: .error(
131: "Could not close the FileInputStream of conf/archive.conf",
132: e);
133: }
134: fis = null;
135: }
136: }
137: _cycleTime = 60000 * Long.parseLong(PropertyHelper.getProperty(
138: _props, "cycleTime"));
139: if (_runHandler != null) {
140: _runHandler.cancel();
141: }
142: _runHandler = new TimerTask() {
143: public void run() {
144: Collection<SectionInterface> sectionsToCheck = getGlobalContext()
145: .getSectionManager().getSections();
146: for (SectionInterface section : sectionsToCheck) {
147: ArchiveType archiveType = getArchiveType(section);
148:
149: if (archiveType == null) {
150: continue;
151: }
152:
153: new ArchiveHandler(archiveType).start();
154: }
155: }
156: };
157: getGlobalContext().getTimer().schedule(_runHandler, 0,
158: _cycleTime);
159: }
160:
161: public void unload() {
162: if (_runHandler != null) {
163: _runHandler.cancel();
164: }
165: }
166:
167: public synchronized boolean removeArchiveHandler(
168: ArchiveHandler handler) {
169: for (Iterator iter = _archiveHandlers.iterator(); iter
170: .hasNext();) {
171: ArchiveHandler ah = (ArchiveHandler) iter.next();
172:
173: if (ah == handler) {
174: iter.remove();
175:
176: return true;
177: }
178: }
179:
180: return false;
181: }
182:
183: public Collection<ArchiveHandler> getArchiveHandlers() {
184: return Collections.unmodifiableCollection(_archiveHandlers);
185: }
186:
187: public synchronized void addArchiveHandler(ArchiveHandler handler)
188: throws DuplicateArchiveException {
189: checkPathForArchiveStatus(handler.getArchiveType()
190: .getDirectory().getPath());
191: _archiveHandlers.add(handler);
192: }
193:
194: public void checkPathForArchiveStatus(String handlerPath)
195: throws DuplicateArchiveException {
196: for (Iterator iter = _archiveHandlers.iterator(); iter
197: .hasNext();) {
198: ArchiveHandler ah = (ArchiveHandler) iter.next();
199: String ahPath = ah.getArchiveType().getDirectory()
200: .getPath();
201:
202: if (ahPath.length() > handlerPath.length()) {
203: if (ahPath.startsWith(handlerPath)) {
204: throw new DuplicateArchiveException(ahPath
205: + " is already being archived");
206: }
207: } else {
208: if (handlerPath.startsWith(ahPath)) {
209: throw new DuplicateArchiveException(handlerPath
210: + " is already being archived");
211: }
212: }
213: }
214: }
215: }
|