1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package net.sf.hermesftp.cmd;
26
27 import java.io.File;
28 import java.io.IOException;
29 import java.text.MessageFormat;
30
31 import net.sf.hermesftp.common.FtpConstants;
32 import net.sf.hermesftp.common.FtpSessionContext;
33
34 import org.apache.commons.io.FilenameUtils;
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37
38 /***
39 * Abstract ancestor of FTP command classes that provides some functionallity shared by different
40 * command classes.
41 *
42 * @author Lars Behnke
43 */
44 public abstract class AbstractFtpCmd implements FtpCmd, FtpConstants {
45
46 private static Log log = LogFactory.getLog(AbstractFtpCmd.class);
47
48 private String token;
49
50 private String arguments;
51
52 private FtpSessionContext ctx;
53
54 private boolean responded;
55
56 /***
57 * Returns a message resource string.
58 *
59 * @param msgKey The message key.
60 * @param args The arguments.
61 * @return The message.
62 */
63 protected String msg(String msgKey, Object[] args) {
64 String msg = msg(msgKey);
65 if (args != null) {
66 msg = MessageFormat.format(msg, args);
67 }
68 return msg;
69 }
70
71 /***
72 * Returns a message resource string.
73 *
74 * @param msgKey The message key.
75 * @return The message.
76 */
77 protected String msg(String msgKey) {
78 return getCtx().getRes(msgKey);
79 }
80
81 /***
82 * Returns a message resource string.
83 *
84 * @param msgKey The message key.
85 * @param arg An single message argument.
86 * @return The message.
87 */
88 protected String msg(String msgKey, String arg) {
89 return msg(msgKey, new Object[] {arg});
90 }
91
92 /***
93 * Writes out the response to a client command.
94 *
95 * @param text The response.
96 */
97 protected void out(String text) {
98 responded = !text.startsWith("150");
99 getCtx().getClientResponseWriter().println(text);
100 getCtx().getClientResponseWriter().flush();
101 }
102
103 /***
104 * Writes the message identified by the passed key to the control stream. If additional
105 * arguments are passed they are integrated into the message string.
106 *
107 * @param msgKey The message key as defined in the resource file.
108 * @param args The optional arguments.
109 */
110 protected void msgOut(String msgKey, Object[] args) {
111 String msg = msg(msgKey, args);
112 out(msg);
113 }
114
115 /***
116 * Convenience method that prints out a message to the control channel..
117 *
118 * @param msgKey The key of the message.
119 */
120 protected void msgOut(String msgKey) {
121 msgOut(msgKey, (Object[]) null);
122 }
123
124 /***
125 * Convenience method that prints out a message to the control channel.
126 *
127 * @param msgKey The key of the message.
128 * @param argument Text argument.
129 */
130 protected void msgOut(String msgKey, String argument) {
131 msgOut(msgKey, new Object[] {argument});
132 }
133
134 /***
135 * Returns a path argument.
136 *
137 * @return The path
138 */
139 protected String getPathArg() {
140 return getAbsPath(getArguments());
141 }
142
143 /***
144 * Returns the absolute path of the passed rel. path.
145 *
146 * @param path The relative path;
147 * @return The absolute path
148 */
149 protected String getAbsPath(String path) {
150 String result;
151 try {
152 path = FilenameUtils.normalizeNoEndSeparator(path);
153 if (path.startsWith(File.separator)) {
154 result = new File(getCtx().getOptions().getRootDir(), path.substring(1)).getCanonicalPath();
155 } else {
156 result = new File(getCtx().getRemoteDir(), path).getCanonicalPath();
157 }
158 } catch (IOException e) {
159 result = getCtx().getRemoteDir();
160 log.error(e);
161 }
162 return result;
163 }
164
165 /***
166 * @return Returns the file offset to be used, or null not offset defined.
167 */
168 protected long getAndResetFileOffset() {
169 Long fileOffsetObj = (Long) getCtx().getAttribute(ATTR_FILE_OFFSET);
170 getCtx().setAttribute(ATTR_FILE_OFFSET, null);
171 long fileOffset = fileOffsetObj == null ? 0 : fileOffsetObj.longValue();
172 return fileOffset;
173 }
174
175 /***
176 * {@inheritDoc}
177 */
178 public void setArguments(String args) {
179 this.arguments = args;
180
181 }
182
183 /***
184 * Returns the arguments previously passed to the instance.
185 *
186 * @return the command line arguments.
187 */
188 public String getArguments() {
189 return arguments;
190 }
191
192 /***
193 * Getter method for the java bean <code>ctx</code>.
194 *
195 * @return Returns the value of the java bean <code>ctx</code>.
196 */
197 public FtpSessionContext getCtx() {
198 return ctx;
199 }
200
201 /***
202 * Setter method for the java bean <code>ctx</code>.
203 *
204 * @param ctx The value of ctx to set.
205 */
206 public void setCtx(FtpSessionContext ctx) {
207 this.ctx = ctx;
208 }
209
210 /***
211 * Gets the permission on the current path.
212 *
213 * @return The permission constant.
214 */
215 public int getPermission() {
216 return getCtx().getPermission(getCtx().getRemoteDir());
217 }
218
219 /***
220 * Returns the command token.
221 *
222 * @return The command token.
223 */
224 public String getToken() {
225 return token;
226 }
227
228 /***
229 * {@inheritDoc}
230 */
231 public void setToken(String token) {
232 this.token = token;
233 }
234
235 /***
236 * @return True if response has been sent.
237 */
238 public boolean isResponded() {
239 return responded;
240 }
241
242 /***
243 * {@inheritDoc}
244 */
245 public boolean handleAsyncCmd(String req) {
246 return false;
247 }
248 }