1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package net.sf.hermesftp.utils;
26
27 import java.io.File;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.io.InputStreamReader;
31 import java.io.StringWriter;
32 import java.lang.reflect.InvocationTargetException;
33 import java.lang.reflect.Method;
34 import java.text.DateFormat;
35 import java.text.MessageFormat;
36 import java.text.SimpleDateFormat;
37 import java.util.Date;
38 import java.util.Locale;
39 import java.util.Properties;
40 import java.util.StringTokenizer;
41
42 import org.apache.commons.lang.StringUtils;
43 import org.springframework.beans.BeanUtils;
44
45 /***
46 * This class contains some functionallity concerning I/O communication not covered by
47 * {@link org.apache.commons.io.IOUtils}.
48 *
49 * @author Lars Behnke
50 */
51 public final class IOUtils {
52
53 private static final int FILE_SIZE_LENGTH_UNIX = 11;
54
55 private static final DateFormat DATE_FORMAT_UNIX = new SimpleDateFormat("MMM dd HH:mm", Locale.US);
56
57 private static final String APP_PROPERTIES = "/app.properties";
58
59 private static Properties appProperties;
60
61 /***
62 * Constructor hidden.
63 */
64 private IOUtils() {
65 super();
66 }
67
68 /***
69 * Closes a file, socket, stream, writer etc. without throwing exceptions. Any exception is
70 * catched and logged. In contrast to the "Commons IO" method <code>closeQuietly()</code> this
71 * method closes any object that has a <code>close()</code>-method and is not restricted to
72 * readers, writers and streams.
73 *
74 * @param o The object to be closed.
75 * @return True, if object could be closed.
76 */
77 public static boolean closeGracefully(Object o) {
78 boolean result;
79 try {
80 Method closeMethod = BeanUtils.findMethod(o.getClass(), "close", null);
81 closeMethod.invoke(o, (Object[]) null);
82 result = true;
83 } catch (IllegalArgumentException e) {
84 result = false;
85 } catch (IllegalAccessException e) {
86 result = false;
87 } catch (InvocationTargetException e) {
88 result = false;
89 } catch (NullPointerException e) {
90 result = false;
91 }
92 return result;
93 }
94
95 /***
96 * Returns a line formated directory entry. The permissions are set as follows: The passed read
97 * flag is relevant for owner, group and others. The passed write flag is only relevant for the
98 * owner.
99 *
100 * @param file The file to be formatted.
101 * @param read True if readable.
102 * @param write True if writable.
103 * @return The formatted line.
104 */
105 public static String formatUnixFtpFileInfo(File file, boolean read, boolean write) {
106 long size;
107 StringBuffer sb = new StringBuffer();
108 String wFlag = write ? "w" : "-";
109 String rFlag = read ? "r" : "-";
110 String permflags;
111 if (file.isDirectory()) {
112 permflags = MessageFormat.format("d{0}{1}x{0}-x{0}-x", new Object[] {rFlag, wFlag});
113 size = 0;
114 } else {
115 permflags = MessageFormat.format("-{0}{1}-{0}--{0}--", new Object[] {rFlag, wFlag});
116 size = file.length();
117 }
118 Date date = new Date(file.lastModified());
119 sb.append(permflags);
120 sb.append(" 1 ftp ftp ");
121 sb.append(StringUtils.leftPad("" + size, FILE_SIZE_LENGTH_UNIX));
122 sb.append(" ");
123 sb.append(DATE_FORMAT_UNIX.format(date));
124 sb.append(" ");
125 sb.append(file.getName());
126 return sb.toString();
127 }
128
129 /***
130 * Reads an arbitrary text resource from the class path.
131 *
132 * @param name The name of the resource.
133 * @param encoding The text encoding.
134 * @return The text.
135 * @throws IOException Error on accessing the resource.
136 */
137 public static String loadTextResource(String name, String encoding) throws IOException {
138 String result = null;
139 StringWriter sw = null;
140 InputStreamReader isr = null;
141 if (encoding == null) {
142 encoding = "UTF-8";
143 }
144 try {
145 InputStream is = IOUtils.class.getResourceAsStream(name);
146 isr = new InputStreamReader(is, encoding);
147 sw = new StringWriter();
148 int c;
149 while ((c = isr.read()) != -1) {
150 sw.write(c);
151 }
152 result = sw.getBuffer().toString();
153 } finally {
154 closeGracefully(isr);
155 closeGracefully(sw);
156 }
157 return result;
158 }
159
160 /***
161 * Returns application properties (app.properties).
162 *
163 * @return The properties object.
164 */
165 public static Properties getAppProperties() {
166 if (appProperties == null) {
167 appProperties = new Properties();
168 InputStream is = IOUtils.class.getResourceAsStream(APP_PROPERTIES);
169 try {
170 appProperties.load(is);
171 } catch (IOException e) {
172 e.printStackTrace(System.out);
173 }
174 }
175 return appProperties;
176 }
177
178 /***
179 * Tries to figure out the application's home directory.
180 *
181 * @return The directory.
182 */
183 public static File getHomeDir() {
184 File result = null;
185 String cp = System.getProperty("java.class.path");
186 StringTokenizer tokenizer = new StringTokenizer(cp, File.pathSeparator);
187 if (tokenizer.countTokens() == 1) {
188 File jar = new File(tokenizer.nextToken());
189 try {
190 result = jar.getCanonicalFile().getParentFile().getParentFile();
191 } catch (IOException e) {
192 }
193 } else {
194 File userDir = new File(System.getProperty("user.dir"));
195 result = userDir.getAbsoluteFile().getParentFile();
196 }
197 return result;
198 }
199
200 /***
201 * Checks, if UNC file naming is supported.
202 *
203 * @return True, if UNC supported.
204 */
205 public static boolean isUNCSupported() {
206 return System.getProperty("os.name").startsWith("Windows");
207 }
208 }