Package org.jnode.command.file

Source Code of org.jnode.command.file.HeadCommand

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.command.file;

import org.jnode.shell.AbstractCommand;
import org.jnode.shell.syntax.Argument;
import org.jnode.shell.syntax.FlagArgument;
import org.jnode.shell.syntax.FileArgument;
import org.jnode.shell.syntax.StringArgument;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.LineNumberReader;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;

/**
* TODO add support for -c -<int> on stdin
* @author chris boertien
*/
public class HeadCommand extends AbstractCommand {

    private static final String help_files = "Print the first 10 lines of each file to stdout, with multiple files a " +
                                             "header giving the file name is printed. With no file, or if file is - " +
                                             "read standard in.";
    private static final String help_bytes = "output the first <int> bytes, or output all but the last -<int> bytes.";
    private static final String help_lines = "output the first <int> lines, or output all but the last -<int> lines.";
    private static final String help_quiet = "never output headers giving file names";
    private static final String help_verbose = "always output headers giving file names";
   
    private final FileArgument Files;
    private final StringArgument Lines;
    private final StringArgument Bytes;
    private final FlagArgument Quiet;
    private final FlagArgument Verbose;
   
    private PrintWriter err;
   
    private int count;
    private boolean headers;
    private boolean useLines;
    private boolean reverse;
    private boolean first = true;
   
    public HeadCommand() {
        super("Print the head of a list of files, or stdin");
        Files   = new FileArgument("files", Argument.MULTIPLE | Argument.OPTIONAL, help_files);
        Lines   = new StringArgument("lines", Argument.OPTIONAL | Argument.EXISTING, help_lines);
        Bytes   = new StringArgument("bytes", Argument.OPTIONAL | Argument.EXISTING, help_bytes);
        Quiet   = new FlagArgument("quiet", Argument.OPTIONAL, help_quiet);
        Verbose = new FlagArgument("verbose", Argument.OPTIONAL, help_verbose);
        registerArguments(Files, Lines, Bytes, Quiet, Verbose);
    }
   
    public void execute() {
        File[] files;
        err      = getError().getPrintWriter();
        headers  = getHeaders();
        useLines = getCountType();
        count    = getCount();
        reverse  = getReversed();
       
        if (!Files.isSet()) {
            files = new File[1];
            files[0] = new File("-");
        } else {
            files = Files.getValues();
        }
       
        try {
            for (File file : files) {
                printHeader(file.getPath());
                if (file.getName().equals("-")) {
                    if (useLines) {
                        printStdinLines();
                    } else {
                        printStdinBytes();
                    }
                } else {
                    if (useLines) {
                        printFileLines(file);
                    } else {
                        printFileBytes(file);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            exit(1);
        }
    }
   
    private void printStdinLines() {
        try {
            printLines(new LineNumberReader(new InputStreamReader(getInput().getInputStream())));
        } catch (IOException ex) {
            err.println(ex);
        }
    }
   
    private void printStdinBytes() {
        try {
            printBytes(getInput().getInputStream(), -1);
        } catch (IOException ex) {
            err.println(ex);
        }
    }
   
    private void printFileLines(File file) {
        LineNumberReader reader = null;
        try {
            reader = new LineNumberReader(new FileReader(file));
            printLines(reader);
        } catch (IOException ex) {
            err.println(ex);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException _) {
                    // ignore
                }
            }
        }
    }
   
    private void printFileBytes(File file) {
        InputStream in = null;
        try {
            in = new FileInputStream(file);
            printBytes(in, (int) file.length());
        } catch (IOException ex) {
            err.println(ex);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException _) {
                    // ignore
                }
            }
        }
    }
   
    private void printLines(LineNumberReader reader) throws IOException {
        PrintWriter out = getOutput().getPrintWriter();
        String line;
        if (!reverse) {
            int n = count;
            while (--n >= 0 && (line = reader.readLine()) != null) {
                out.println(line);
            }
        } else {
            List<String> lines = new ArrayList<String>();
           
            while ((line = reader.readLine()) != null) {
                lines.add(line);
            }
           
            int numLines = lines.size() - count;
            for (int n = 0; n < numLines; n++) {
                out.println(lines.get(n));
            }
        }
    }
   
    private void printBytes(InputStream in, int size) throws IOException {
        OutputStream out = getOutput().getOutputStream();
        byte[] buffer;
        int len;
        int n;
        int bufsize = 8 * 1024;
       
        if (!reverse) {
            n = count;
        } else if (size != -1) {
            n = size - count;
        } else {
            // FIXME
            throw new UnsupportedOperationException("Cannot do -count byte reads on stdin yet");
        }
       
        buffer = new byte[Math.min(n, bufsize)];
        while (n > 0 && (len = in.read(buffer)) > 0) {
            len = Math.min(n, len);
            out.write(buffer, 0, len);
            n -= len;
        }
    }
   
    private void printHeader(String name) {
        PrintWriter out = getOutput().getPrintWriter();
        if (headers) {
            if (!first) {
                out.println();
            }
            first = false;
            if (name.equals("-")) {
                out.println("==> standard input <==");
            } else {
                out.println("==> " + name + " <==");
            }
        }
    }
   
    private boolean getHeaders() {
        if (Quiet.isSet()) {
            return false;
        } else if (Verbose.isSet()) {
            return true;
        } else {
            return headers = Files.isSet() && Files.getValues().length > 1;
        }
    }
   
    private boolean getCountType() {
        return !Bytes.isSet();
    }
   
    private int getCount() {
        int count = 10;
        if (Bytes.isSet()) {
            count = parseInt(Bytes.getValue());
        }
        if (Lines.isSet()) {
            count = parseInt(Lines.getValue());
        }
        return count < 0 ? 10 : count;
    }
   
    private boolean getReversed() {
        if (Bytes.isSet()) {
            return Bytes.getValue().charAt(0) == '-';
        } else if (Lines.isSet()) {
            return Lines.getValue().charAt(0) == '-';
        }
        return false;
    }
   
    private int parseInt(String s) {
        if (s.charAt(0) == '-') {
            s = s.substring(1);
        }
        try {
            return Integer.parseInt(s);
        } catch (NumberFormatException ex) {
            return -1;
        }
    }
}
TOP

Related Classes of org.jnode.command.file.HeadCommand

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.