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.commands;
019:
020: import net.sf.drftpd.ObjectNotFoundException;
021: import net.sf.drftpd.master.BaseFtpConnection;
022: import net.sf.drftpd.master.command.CommandManager;
023: import net.sf.drftpd.master.command.CommandManagerFactory;
024:
025: import org.apache.log4j.Logger;
026:
027: import org.drftpd.master.RemoteSlave;
028: import org.drftpd.mirroring.ArchiveHandler;
029: import org.drftpd.mirroring.ArchiveType;
030: import org.drftpd.mirroring.DuplicateArchiveException;
031: import org.drftpd.plugins.Archive;
032:
033: import org.drftpd.remotefile.LinkedRemoteFileInterface;
034: import org.drftpd.sections.SectionInterface;
035:
036: import org.tanesha.replacer.ReplacerEnvironment;
037:
038: import java.io.FileNotFoundException;
039:
040: import java.lang.reflect.Constructor;
041:
042: import java.util.HashSet;
043: import java.util.Iterator;
044: import java.util.Properties;
045: import java.util.StringTokenizer;
046:
047: /*
048: * @author zubov
049: * @version $Id: ArchiveCommandHandler.java 1320 2005-10-15 21:42:03Z zubov $
050: */
051: public class ArchiveCommandHandler implements CommandHandler,
052: CommandHandlerFactory {
053: private static final Logger logger = Logger
054: .getLogger(ArchiveCommandHandler.class);
055:
056: public ArchiveCommandHandler() {
057: super ();
058: }
059:
060: public Reply execute(BaseFtpConnection conn)
061: throws UnhandledCommandException, ImproperUsageException {
062: String cmd = conn.getRequest().getCommand();
063:
064: if ("SITE LISTARCHIVETYPES".equals(cmd)) {
065: return doLISTARCHIVETYPES(conn);
066: }
067:
068: if ("SITE ARCHIVE".equals(cmd)) {
069: return doARCHIVE(conn);
070: }
071:
072: throw UnhandledCommandException.create(
073: ArchiveCommandHandler.class, conn.getRequest());
074: }
075:
076: private Reply doARCHIVE(BaseFtpConnection conn)
077: throws ImproperUsageException {
078: Reply reply = new Reply(200);
079: ReplacerEnvironment env = new ReplacerEnvironment();
080:
081: if (!conn.getRequest().hasArgument()) {
082: throw new ImproperUsageException();
083: }
084:
085: StringTokenizer st = new StringTokenizer(conn.getRequest()
086: .getArgument());
087: String dirname = st.nextToken();
088: LinkedRemoteFileInterface lrf;
089:
090: try {
091: lrf = conn.getCurrentDirectory().getFile(dirname);
092: } catch (FileNotFoundException e1) {
093: try {
094: lrf = conn.getGlobalContext().getConnectionManager()
095: .getGlobalContext().getRoot().lookupFile(
096: dirname);
097: } catch (FileNotFoundException e2) {
098: reply.addComment(conn.jprintf(
099: ArchiveCommandHandler.class, "help.archive",
100: env));
101: env.add("dirname", dirname);
102: reply.addComment(conn.jprintf(
103: ArchiveCommandHandler.class, "archive.baddir",
104: env));
105:
106: return reply;
107: }
108: }
109:
110: Archive archive;
111:
112: try {
113: archive = (Archive) conn.getGlobalContext().getFtpListener(
114: Archive.class);
115: } catch (ObjectNotFoundException e3) {
116: reply.addComment(conn.jprintf(ArchiveCommandHandler.class,
117: "archive.loadarchive", env));
118:
119: return reply;
120: }
121:
122: String archiveTypeName = null;
123: ArchiveType archiveType = null;
124: SectionInterface section = conn.getGlobalContext()
125: .getSectionManager().lookup(lrf.getPath());
126:
127: if (st.hasMoreTokens()) { // load the specific type
128: archiveTypeName = st.nextToken();
129:
130: Class[] classParams = { org.drftpd.plugins.Archive.class,
131: SectionInterface.class, Properties.class };
132: Constructor constructor = null;
133:
134: try {
135: constructor = Class.forName(
136: "org.drftpd.mirroring.archivetypes."
137: + archiveTypeName).getConstructor(
138: classParams);
139: } catch (Exception e1) {
140: logger
141: .debug(
142: "Serious error, your ArchiveType for section "
143: + section.getName()
144: + " is incompatible with this version of DrFTPD",
145: e1);
146: reply.addComment(conn.jprintf(
147: ArchiveCommandHandler.class,
148: "archive.incompatible", env));
149:
150: return reply;
151: }
152:
153: Properties props = new Properties();
154:
155: while (st.hasMoreTokens()) {
156: addConfig(props, st.nextToken(), section);
157: }
158:
159: Object[] objectParams = { archive, section, props };
160:
161: try {
162: archiveType = (ArchiveType) constructor
163: .newInstance(objectParams);
164: } catch (Exception e2) {
165: logger.warn("Unable to load ArchiveType for section "
166: + section.getName(), e2);
167: env.add("exception", e2.getMessage());
168: reply.addComment(conn.jprintf(
169: ArchiveCommandHandler.class,
170: "archive.badarchivetype", env));
171:
172: return reply;
173: }
174: }
175:
176: if (archiveType == null) {
177: archiveType = archive.getArchiveType(section);
178: }
179:
180: if (archiveTypeName == null) {
181: archiveTypeName = archiveType.getClass().getName();
182: }
183:
184: HashSet<RemoteSlave> slaveSet = new HashSet<RemoteSlave>();
185:
186: while (st.hasMoreTokens()) {
187: String slavename = st.nextToken();
188:
189: try {
190: RemoteSlave rslave = conn.getGlobalContext()
191: .getConnectionManager().getGlobalContext()
192: .getSlaveManager().getRemoteSlave(slavename);
193: slaveSet.add(rslave);
194: } catch (ObjectNotFoundException e2) {
195: env.add("slavename", slavename);
196: reply.addComment(conn.jprintf(
197: ArchiveCommandHandler.class,
198: "archive.badslave", env));
199: }
200: }
201:
202: archiveType.setDirectory(lrf);
203:
204: try {
205: archive.checkPathForArchiveStatus(lrf.getPath());
206: } catch (DuplicateArchiveException e) {
207: env.add("exception", e.getMessage());
208: reply.addComment(conn.jprintf(ArchiveCommandHandler.class,
209: "archive.fail", env));
210: }
211:
212: if (!slaveSet.isEmpty()) {
213: archiveType.setRSlaves(slaveSet);
214: }
215:
216: ArchiveHandler archiveHandler = new ArchiveHandler(archiveType);
217:
218: archiveHandler.start();
219: env.add("dirname", lrf.getPath());
220: env.add("archivetypename", archiveTypeName);
221: reply.addComment(conn.jprintf(ArchiveCommandHandler.class,
222: "archive.success", env));
223:
224: return reply;
225: }
226:
227: private void addConfig(Properties props, String string,
228: SectionInterface section) {
229: if (string.indexOf('=') == -1) {
230: throw new IllegalArgumentException(
231: string
232: + " does not contain an = and is therefore not a property");
233: }
234:
235: String[] data = string.split("=");
236:
237: if (data.length != 2) {
238: throw new IllegalArgumentException(
239: string
240: + " is therefore not a property because it has no definite key");
241: }
242:
243: if (props.containsKey(data[0])) {
244: throw new IllegalArgumentException(string
245: + " is already contained in the Properties");
246: }
247:
248: props.put(section.getName() + "." + data[0], data[1]);
249: }
250:
251: private Reply doLISTARCHIVETYPES(BaseFtpConnection conn) {
252: Reply reply = new Reply(200);
253: int x = 0;
254: ReplacerEnvironment env = new ReplacerEnvironment();
255: Archive archive;
256:
257: try {
258: archive = (Archive) conn.getGlobalContext()
259: .getConnectionManager().getGlobalContext()
260: .getFtpListener(Archive.class);
261: } catch (ObjectNotFoundException e) {
262: reply.addComment(conn.jprintf(ArchiveCommandHandler.class,
263: "archive.loadarchive", env));
264:
265: return reply;
266: }
267:
268: for (Iterator iter = archive.getArchiveHandlers().iterator(); iter
269: .hasNext(); x++) {
270: ArchiveHandler archiveHandler = (ArchiveHandler) iter
271: .next();
272: reply
273: .addComment(x + ". "
274: + archiveHandler.getArchiveType());
275: }
276:
277: return reply;
278: }
279:
280: public String[] getFeatReplies() {
281: return null;
282: }
283:
284: public CommandHandler initialize(BaseFtpConnection conn,
285: CommandManager initializer) {
286: return this ;
287: }
288:
289: public void load(CommandManagerFactory initializer) {
290: }
291:
292: public void unload() {
293: }
294: }
|