001package org.unix4j.unix.ls; 002 003import java.io.File; 004import java.util.Calendar; 005import java.util.List; 006import java.util.Locale; 007 008import org.unix4j.line.SimpleLine; 009import org.unix4j.processor.LineProcessor; 010import org.unix4j.util.FileUtil; 011import org.unix4j.util.Java7Util; 012import org.unix4j.util.StringUtil; 013 014/** 015 * Formatter for long file output including permissions, owner, size etc. An 016 * example output with long format looks like this: 017 * 018 * <pre> 019 * -rw-r--r--@ 1 myself geeks 1.6K May 8 23:20 EFMTool Test Case.zip 020 * -rw-r--r-- 1 myself myself 2.6M May 5 2011 EM_FX_RANK_2011-1.pages 021 * -rw-r--r-- 1 myself geeks 466K May 5 2011 EM_FX_RANK_2011-1.pdf 022 * -rw-r--r-- 1 myself geeks 1.3M May 5 2011 EM_FX_RANK_2011.pdf 023 * -rw-r--r--@ 1 myself geeks 118M Apr 11 2011 PS_AIO_07_B110_USW_Full_Mac_WW_11.dmg 024 * drwxrwxrwx 5 myself geeks 170B Mar 6 2011 Private Tax 025 * -rw-r--r-- 1 myself myself 37M Apr 26 2011 Scanned Image 111160000.pdf 026 * -rw-r--r-- 1 myself mysel 37M Apr 26 2011 Scanned Image 111160008.pdf 027 * drwxrwxrwx 9 myself geeks 306B Apr 19 2011 aevum 028 * drwxr-xr-x 3 myself geeks 102B Dec 21 2011 baby 029 * drwxr-xr-x 4 myself geeks 136B May 18 2011 bills 030 * drwxrwxrwx 17 myself geeks 578B Jun 15 11:21 cv 031 * </pre> 032 */ 033class LsFormatterLong implements LsFormatter { 034 035 protected final ThreadLocal<Calendar> calendar = new ThreadLocal<Calendar>() { 036 @Override 037 protected Calendar initialValue() { 038 return Calendar.getInstance(); 039 } 040 }; 041 protected final ThreadLocal<Integer> maxSizeStringLength = new ThreadLocal<Integer>() { 042 @Override 043 protected Integer initialValue() { 044 return Integer.valueOf(0); 045 } 046 }; 047 048 protected Calendar getCalendar() { 049 return calendar.get(); 050 } 051 052 @Override 053 public boolean writeFormatted(File relativeTo, File file, LsArguments args, LineProcessor output) { 054 return output.processLine( 055 new SimpleLine( 056 getFilePermissions(file, args) + ' ' + 057 getOwner(file, args) + ' ' + 058 getGroup(file, args) + ' ' + 059 getSize(file, args) + ' ' + 060 getDateTime(file, args) + ' ' + 061 getName(relativeTo, file, args) 062 ) 063 ); 064 } 065 066 protected String getFilePermissions(File file, LsArguments args) { 067 final boolean r = file.canRead(); 068 final boolean w = file.canWrite(); 069 final boolean x = file.canExecute(); 070 return (file.isDirectory() ? "d" : "-") + 071 //owner 072 (r ? 'r' : '-') + 073 (w ? 'w' : '-') + 074 (x ? 'x' : '-') + 075 //group 076 (r ? '.' : '-') + 077 (w ? '.' : '-') + 078 (x ? '.' : '-') + 079 //other 080 (r ? '.' : '-') + 081 (w ? '.' : '-') + 082 (x ? '.' : '-'); 083 } 084 085 protected String getOwner(File file, LsArguments args) { 086 return StringUtil.fixSizeString(7, true, "???"); 087 } 088 089 protected String getGroup(File file, LsArguments args) { 090 return StringUtil.fixSizeString(7, true, "???"); 091 } 092 093 protected String getSize(File file, LsArguments args) { 094 final String sizeString = LsCommand.getSizeString(args, file.length()); 095 return StringUtil.fixSizeString(maxSizeStringLength.get(), false, sizeString); 096 } 097 098 protected long getLastModifiedMS(File file, LsArguments args) { 099 return file.lastModified(); 100 } 101 102 protected String getDateTime(File file, LsArguments args) { 103 final Calendar cal = calendar.get(); 104 cal.setTimeInMillis(System.currentTimeMillis());//set current date to get current year below 105 final int curYear = cal.get(Calendar.YEAR); 106 cal.setTimeInMillis(getLastModifiedMS(file, args)); 107 final int fileYear = cal.get(Calendar.YEAR); 108 final String month = cal.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.getDefault()); 109 110 final String sM = StringUtil.fixSizeString(3, true, month); 111 final String sD = StringUtil.fixSizeString(2, false, ' ', cal.get(Calendar.DAY_OF_MONTH)); 112 if (curYear == fileYear) { 113 final String sHou = StringUtil.fixSizeString(2, false, '0', cal.get(Calendar.HOUR_OF_DAY)); 114 final String sMin = StringUtil.fixSizeString(2, false, '0', cal.get(Calendar.MINUTE)); 115 return sM + ' ' + sD + ' ' + sHou + ':' + sMin; 116 } else { 117 final String sY = StringUtil.fixSizeString(5, false, ' ', fileYear); 118 return sM + ' ' + sD + ' ' + sY; 119 } 120 } 121 122 protected String getName(File relativeTo, File file, LsArguments args) { 123 return FileUtil.getRelativePath(relativeTo, file); 124 } 125 126 static Factory FACTORY = new Factory() { 127 @Override 128 public LsFormatter create(File relativeTo, File directory, List<File> directoryFiles, LsArguments args) { 129 final LsFormatterLong fmt = Java7Util.newInstance(LsFormatterLong.class, new LsFormatterLong()); 130 fmt.maxSizeStringLength.set(calculateMaxSizeStringLength(directoryFiles, args)); 131 return fmt; 132 } 133 134 private int calculateMaxSizeStringLength(List<File> directoryFiles, LsArguments args) { 135 int maxSizeStringLength = 0; 136 for (final File f : directoryFiles) { 137 if (f.isFile()) { 138 if (f.isFile()) { 139 final String sizeString = LsCommand.getSizeString(args, f.length()); 140 maxSizeStringLength = Math.max(maxSizeStringLength, sizeString.length()); 141 } 142 } 143 } 144 return maxSizeStringLength; 145 } 146 }; 147 148}