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    }