001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.vfs2.example;
018
019 import java.io.BufferedReader;
020 import java.io.IOException;
021 import java.io.InputStreamReader;
022 import java.text.DateFormat;
023 import java.util.ArrayList;
024 import java.util.Date;
025 import java.util.StringTokenizer;
026
027 import org.apache.commons.vfs2.FileContent;
028 import org.apache.commons.vfs2.FileObject;
029 import org.apache.commons.vfs2.FileSystemException;
030 import org.apache.commons.vfs2.FileSystemManager;
031 import org.apache.commons.vfs2.FileType;
032 import org.apache.commons.vfs2.FileUtil;
033 import org.apache.commons.vfs2.Selectors;
034 import org.apache.commons.vfs2.VFS;
035
036 /**
037 * A simple command-line shell for performing file operations.
038 *
039 * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
040 * @author Gary D. Gregory
041 */
042 public class Shell
043 {
044 private static final String CVS_ID = "$Id:Shell.java 232419 2005-08-13 07:23:40 +0200 (Sa, 13 Aug 2005) imario $";
045 private final FileSystemManager mgr;
046 private FileObject cwd;
047 private BufferedReader reader;
048
049 public static void main(final String[] args)
050 {
051 try
052 {
053 (new Shell()).go();
054 }
055 catch (Exception e)
056 {
057 e.printStackTrace();
058 System.exit(1);
059 }
060 System.exit(0);
061 }
062
063 private Shell() throws FileSystemException
064 {
065 mgr = VFS.getManager();
066 cwd = mgr.resolveFile(System.getProperty("user.dir"));
067 reader = new BufferedReader(new InputStreamReader(System.in));
068 }
069
070 private void go() throws Exception
071 {
072 System.out.println("VFS Shell [" + CVS_ID + "]");
073 while (true)
074 {
075 final String[] cmd = nextCommand();
076 if (cmd == null)
077 {
078 return;
079 }
080 if (cmd.length == 0)
081 {
082 continue;
083 }
084 final String cmdName = cmd[0];
085 if (cmdName.equalsIgnoreCase("exit") || cmdName.equalsIgnoreCase("quit"))
086 {
087 return;
088 }
089 try
090 {
091 handleCommand(cmd);
092 }
093 catch (final Exception e)
094 {
095 System.err.println("Command failed:");
096 e.printStackTrace(System.err);
097 }
098 }
099 }
100
101 /**
102 * Handles a command.
103 */
104 private void handleCommand(final String[] cmd) throws Exception
105 {
106 final String cmdName = cmd[0];
107 if (cmdName.equalsIgnoreCase("cat"))
108 {
109 cat(cmd);
110 }
111 else if (cmdName.equalsIgnoreCase("cd"))
112 {
113 cd(cmd);
114 }
115 else if (cmdName.equalsIgnoreCase("cp"))
116 {
117 cp(cmd);
118 }
119 else if (cmdName.equalsIgnoreCase("help"))
120 {
121 help();
122 }
123 else if (cmdName.equalsIgnoreCase("ls"))
124 {
125 ls(cmd);
126 }
127 else if (cmdName.equalsIgnoreCase("pwd"))
128 {
129 pwd();
130 }
131 else if (cmdName.equalsIgnoreCase("rm"))
132 {
133 rm(cmd);
134 }
135 else if (cmdName.equalsIgnoreCase("touch"))
136 {
137 touch(cmd);
138 }
139 else
140 {
141 System.err.println("Unknown command \"" + cmdName + "\".");
142 }
143 }
144
145 /**
146 * Does a 'help' command.
147 */
148 private void help()
149 {
150 System.out.println("Commands:");
151 System.out.println("cat <file> Displays the contents of a file.");
152 System.out.println("cd [folder] Changes current folder.");
153 System.out.println("cp <src> <dest> Copies a file or folder.");
154 System.out.println("help Shows this message.");
155 System.out.println("ls [-R] [path] Lists contents of a file or folder.");
156 System.out.println("pwd Displays current folder.");
157 System.out.println("rm <path> Deletes a file or folder.");
158 System.out.println("touch <path> Sets the last-modified time of a file.");
159 System.out.println("exit Exits this program.");
160 System.out.println("quit Exits this program.");
161 }
162
163 /**
164 * Does an 'rm' command.
165 */
166 private void rm(final String[] cmd) throws Exception
167 {
168 if (cmd.length < 2)
169 {
170 throw new Exception("USAGE: rm <path>");
171 }
172
173 final FileObject file = mgr.resolveFile(cwd, cmd[1]);
174 file.delete(Selectors.SELECT_SELF);
175 }
176
177 /**
178 * Does a 'cp' command.
179 */
180 private void cp(final String[] cmd) throws Exception
181 {
182 if (cmd.length < 3)
183 {
184 throw new Exception("USAGE: cp <src> <dest>");
185 }
186
187 final FileObject src = mgr.resolveFile(cwd, cmd[1]);
188 FileObject dest = mgr.resolveFile(cwd, cmd[2]);
189 if (dest.exists() && dest.getType() == FileType.FOLDER)
190 {
191 dest = dest.resolveFile(src.getName().getBaseName());
192 }
193
194 dest.copyFrom(src, Selectors.SELECT_ALL);
195 }
196
197 /**
198 * Does a 'cat' command.
199 */
200 private void cat(final String[] cmd) throws Exception
201 {
202 if (cmd.length < 2)
203 {
204 throw new Exception("USAGE: cat <path>");
205 }
206
207 // Locate the file
208 final FileObject file = mgr.resolveFile(cwd, cmd[1]);
209
210 // Dump the contents to System.out
211 FileUtil.writeContent(file, System.out);
212 System.out.println();
213 }
214
215 /**
216 * Does a 'pwd' command.
217 */
218 private void pwd()
219 {
220 System.out.println("Current folder is " + cwd.getName());
221 }
222
223 /**
224 * Does a 'cd' command.
225 * If the taget directory does not exist, a message is printed to <code>System.err</code>.
226 */
227 private void cd(final String[] cmd) throws Exception
228 {
229 final String path;
230 if (cmd.length > 1)
231 {
232 path = cmd[1];
233 }
234 else
235 {
236 path = System.getProperty("user.home");
237 }
238
239 // Locate and validate the folder
240 FileObject tmp = mgr.resolveFile(cwd, path);
241 if (tmp.exists())
242 {
243 cwd = tmp;
244 }
245 else
246 {
247 System.out.println("Folder does not exist: " + tmp.getName());
248 }
249 System.out.println("Current folder is " + cwd.getName());
250 }
251
252 /**
253 * Does an 'ls' command.
254 */
255 private void ls(final String[] cmd) throws FileSystemException
256 {
257 int pos = 1;
258 final boolean recursive;
259 if (cmd.length > pos && cmd[pos].equals("-R"))
260 {
261 recursive = true;
262 pos++;
263 }
264 else
265 {
266 recursive = false;
267 }
268
269 final FileObject file;
270 if (cmd.length > pos)
271 {
272 file = mgr.resolveFile(cwd, cmd[pos]);
273 }
274 else
275 {
276 file = cwd;
277 }
278
279 if (file.getType() == FileType.FOLDER)
280 {
281 // List the contents
282 System.out.println("Contents of " + file.getName());
283 listChildren(file, recursive, "");
284 }
285 else
286 {
287 // Stat the file
288 System.out.println(file.getName());
289 final FileContent content = file.getContent();
290 System.out.println("Size: " + content.getSize() + " bytes.");
291 final DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
292 final String lastMod = dateFormat.format(new Date(content.getLastModifiedTime()));
293 System.out.println("Last modified: " + lastMod);
294 }
295 }
296
297 /**
298 * Does a 'touch' command.
299 */
300 private void touch(final String[] cmd) throws Exception
301 {
302 if (cmd.length < 2)
303 {
304 throw new Exception("USAGE: touch <path>");
305 }
306 final FileObject file = mgr.resolveFile(cwd, cmd[1]);
307 if (!file.exists())
308 {
309 file.createFile();
310 }
311 file.getContent().setLastModifiedTime(System.currentTimeMillis());
312 }
313
314 /**
315 * Lists the children of a folder.
316 */
317 private void listChildren(final FileObject dir,
318 final boolean recursive,
319 final String prefix)
320 throws FileSystemException
321 {
322 final FileObject[] children = dir.getChildren();
323 for (int i = 0; i < children.length; i++)
324 {
325 final FileObject child = children[i];
326 System.out.print(prefix);
327 System.out.print(child.getName().getBaseName());
328 if (child.getType() == FileType.FOLDER)
329 {
330 System.out.println("/");
331 if (recursive)
332 {
333 listChildren(child, recursive, prefix + " ");
334 }
335 }
336 else
337 {
338 System.out.println();
339 }
340 }
341 }
342
343 /**
344 * Returns the next command, split into tokens.
345 */
346 private String[] nextCommand() throws IOException
347 {
348 System.out.print("> ");
349 final String line = reader.readLine();
350 if (line == null)
351 {
352 return null;
353 }
354 final ArrayList<String> cmd = new ArrayList<String>();
355 final StringTokenizer tokens = new StringTokenizer(line);
356 while (tokens.hasMoreTokens())
357 {
358 cmd.add(tokens.nextToken());
359 }
360 return cmd.toArray(new String[cmd.size()]);
361 }
362 }