Package org.jboss.aesh.extensions.ls

Source Code of org.jboss.aesh.extensions.ls.Ls$PosixFileComparator

/*
* Copyright 2012 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Eclipse Public License version 1.0, available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.jboss.aesh.extensions.ls;

import java.io.IOException;
import java.math.RoundingMode;
import java.nio.file.LinkOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.DosFileAttributes;
import java.nio.file.attribute.PosixFileAttributes;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import org.jboss.aesh.cl.Arguments;
import org.jboss.aesh.cl.CommandDefinition;
import org.jboss.aesh.cl.Option;
import org.jboss.aesh.comparators.PosixFileNameComparator;
import org.jboss.aesh.console.Config;
import org.jboss.aesh.console.command.Command;
import org.jboss.aesh.console.command.CommandResult;
import org.jboss.aesh.console.command.invocation.CommandInvocation;
import org.jboss.aesh.extensions.grep.AeshPosixFilePermissions;
import org.jboss.aesh.io.filter.NoDotNamesFilter;
import org.jboss.aesh.io.Resource;
import org.jboss.aesh.parser.Parser;
import org.jboss.aesh.terminal.Color;
import org.jboss.aesh.terminal.Shell;
import org.jboss.aesh.terminal.TerminalColor;
import org.jboss.aesh.terminal.TerminalString;

/**
* @author <a href="mailto:stale.pedersen@jboss.org">Ståle W. Pedersen</a>
*/
@CommandDefinition(name = "ls", description = "[OPTION]... [FILE]...\n" +
        "List information about the FILEs (the current directory by default).\n" +
        "Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.\n")
public class Ls implements Command<CommandInvocation> {

    @Option(shortName = 'H', name = "help", hasValue = false,
            description = "display this help and exit")
    private boolean help;
    @Option(shortName = 'a', name = "all", hasValue = false,
    description = "do not ignore entries starting with .")
    private boolean all;
    @Option(shortName = 'd', name = "directory", hasValue = false,
            description = "list directory entries instead of contents, and do not dereference symbolic links")
    private boolean directory;
    @Option(shortName = 'l', name = "longlisting", hasValue = false,
            description = "use a long listing format")
    private boolean longListing;

    @Option(shortName = 's', name = "size", hasValue = false,
            description = "print the allocated size of each file, in blocks")
    private boolean size;

    @Option(shortName = 'h', name ="human-readable", hasValue = false,
            description = "with -l, print sizes in human readable format (e.g., 1K 234M 2G)")
    private boolean humanReadable;

    @Arguments
    private List<Resource> arguments;

    private static final char SPACE = ' ';

    private static final Class<? extends BasicFileAttributes> fileAttributes =
            Config.isOSPOSIXCompatible() ? PosixFileAttributes.class : DosFileAttributes.class;

    private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MMM dd HH:mm");
    private static final DateFormat OLD_FILE_DATE_FORMAT = new SimpleDateFormat("MMM dd  yyyy");

    private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat(".#");

    private static final TerminalColor DIRECTORY_COLOR = new TerminalColor(Color.BLUE, Color.DEFAULT, Color.Intensity.BRIGHT);
    private static final TerminalColor SYMBOLIC_LINK_COLOR = new TerminalColor(Color.CYAN, Color.DEFAULT, Color.Intensity.BRIGHT);

    public Ls() {
        DECIMAL_FORMAT.setRoundingMode(RoundingMode.UP);
    }

    @Override
    public CommandResult execute(CommandInvocation commandInvocation) throws IOException {
        //just display help and return
        if(help) {
            commandInvocation.getShell().out().println(commandInvocation.getHelpInfo("ls"));
            return CommandResult.SUCCESS;
        }

        if(arguments == null) {
            arguments = new ArrayList<>(1);
            arguments.add(commandInvocation.getAeshContext().getCurrentWorkingDirectory());
        }

        int counter = 0;
        for(Resource file : arguments) {
            if(counter > 0) {
                commandInvocation.getShell().out().println(Config.getLineSeparator()+file.getName()+":");
            }

            for(Resource f : file.resolve(commandInvocation.getAeshContext().getCurrentWorkingDirectory())) {
                if(f.isDirectory())
                    displayDirectory(f, commandInvocation.getShell());
                else if(f.isLeaf())
                    displayFile(f,commandInvocation.getShell());
                else if(!f.exists()) {
                    commandInvocation.getShell().out().println("ls: cannot access "+
                            f.toString()+": No such file or directory");
                }
            }
            counter++;
        }

        return CommandResult.SUCCESS;
    }

    private void displayDirectory(Resource input, Shell shell) {
        List<Resource> files = new ArrayList<>();

        if (all) {
            // add "." and ".." to list of files
            files.add(input.newInstance("."));
            files.add(input.newInstance(".."));
            files.addAll(input.list());

        }
        else {
            files = input.list(new NoDotNamesFilter());
        }

        Collections.sort(files, new PosixFileComparator());

        if (longListing) {
            shell.out().print(displayLongListing(files));
        }
        else {
            shell.out().print(Parser.formatDisplayCompactListTerminalString(
                formatFileList(files),
                shell.getSize().getWidth()));
        }
    }

    private List<TerminalString> formatFileList(List<Resource> fileList) {
        ArrayList<TerminalString> list = new ArrayList<>(fileList.size());
        for(Resource file : fileList) {
            if (file.isSymbolicLink()) {
                list.add(new TerminalString(file.getName(), SYMBOLIC_LINK_COLOR));
            } else if (file.isDirectory()) {
                list.add(new TerminalString(file.getName(), DIRECTORY_COLOR));
            } else {
                list.add(new TerminalString(file.getName()));
            }
        }
        return list;
    }

    private void displayFile(Resource input, Shell shell) {
        if(longListing) {
            List<Resource> resourceList = new ArrayList<>(1);
            resourceList.add(input);
            shell.out().print(displayLongListing(resourceList));
        }
        else {
            List<Resource> resourceList = new ArrayList<>(1);
            resourceList.add(input);
            shell.out().print(Parser.formatDisplayListTerminalString(
                    formatFileList(resourceList), shell.getSize().getHeight(), shell.getSize().getWidth()));
        }
    }

    private String displayLongListing(List<Resource> files) {

        StringGroup access = new StringGroup(files.size());
        StringGroup size = new StringGroup(files.size());
        StringGroup owner = new StringGroup(files.size());
        StringGroup group = new StringGroup(files.size());
        StringGroup modified = new StringGroup(files.size());

        try {
            int counter = 0;
            for(Resource file : files) {
                BasicFileAttributes attr = file.readAttributes(fileAttributes, LinkOption.NOFOLLOW_LINKS);

                if (Config.isOSPOSIXCompatible()) {
                    access.addString(AeshPosixFilePermissions.toString(((PosixFileAttributes) attr)), counter);
                } else {
                    access.addString("", counter);
                }

                size.addString(makeSizeReadable(attr.size()), counter);

                if (Config.isOSPOSIXCompatible()) {
                    owner.addString(((PosixFileAttributes) attr).owner().getName(), counter);
                    group.addString(((PosixFileAttributes) attr).group().getName(), counter);
                } else {
                    owner.addString("", counter);
                    group.addString("", counter);
                }

                // show year instead of time when file wasn't changed in actual year
                Date lastModifiedTime = new Date(attr.lastModifiedTime().toMillis());

                Calendar lastModifiedCalendar = Calendar.getInstance();
                lastModifiedCalendar.setTime(lastModifiedTime);

                Calendar nowCalendar = Calendar.getInstance();

                if (lastModifiedCalendar.get(Calendar.YEAR) == nowCalendar.get(Calendar.YEAR)) {
                    modified.addString(DATE_FORMAT.format(lastModifiedTime), counter);
                } else {
                    modified.addString(OLD_FILE_DATE_FORMAT.format(lastModifiedTime), counter);
                }

                counter++;
            }
        }
        catch (IOException e) {
            e.printStackTrace()//To change body of catch statement use File | Settings | File Templates.
        }

        StringBuilder builder = new StringBuilder();

        for (int i = 0; i < files.size(); i++) {
            builder.append(access.getString(i))
                .append(owner.getFormattedStringPadRight(i))
                .append(group.getFormattedStringPadRight(i))
                .append(size.getFormattedString(i))
                .append(SPACE)
                .append(modified.getString(i))
                .append(SPACE);

            if (files.get(i).isSymbolicLink()) {
                builder.append(new TerminalString(files.get(i).getName(), SYMBOLIC_LINK_COLOR));
                builder.append(" -> ");
                try {
                    builder.append(files.get(i).readSymbolicLink());
                } catch (IOException ex) {
                    ex.printStackTrace(); // this should not happen
                }
            } else if (files.get(i).isDirectory()) {
                builder.append(new TerminalString(files.get(i).getName(), DIRECTORY_COLOR));
            } else {
                builder.append(files.get(i).getName());
            }

            builder.append(Config.getLineSeparator());
        }

        return builder.toString();
    }

    private String makeSizeReadable(long size) {
        if(!humanReadable)
            return String.valueOf(size);
        else {
            if(size < 10000)
                return String.valueOf(size);
            else if(size < 10000000) //K
                return DECIMAL_FORMAT.format((double) size/1024)+"K";
            else if(size < 1000000000) //M
                return DECIMAL_FORMAT.format((double) size/(1048576))+"M";
            else
                return DECIMAL_FORMAT.format((double) size/(1048576*1014))+"G";
        }
    }

    class PosixFileComparator implements Comparator<Resource> {
        private PosixFileNameComparator posixFileNameComparator = new PosixFileNameComparator();

        @Override
        public int compare(Resource o1, Resource o2) {
            return posixFileNameComparator.compare(o1.getName(), o2.getName());
        }
    }
}
TOP

Related Classes of org.jboss.aesh.extensions.ls.Ls$PosixFileComparator

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.