1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17   * SOFTWARE.
18   */
19  
20  package com.liferay.portal.util;
21  
22  import com.liferay.portal.kernel.log.Log;
23  import com.liferay.portal.kernel.log.LogFactoryUtil;
24  import com.liferay.portal.kernel.util.ByteArrayMaker;
25  import com.liferay.portal.kernel.util.FileComparator;
26  import com.liferay.portal.kernel.util.GetterUtil;
27  import com.liferay.portal.kernel.util.StringPool;
28  import com.liferay.portal.kernel.util.StringUtil;
29  import com.liferay.portal.kernel.util.Time;
30  import com.liferay.portal.kernel.util.Validator;
31  import com.liferay.util.PwdGenerator;
32  import com.liferay.util.SystemProperties;
33  import com.liferay.util.lucene.JerichoHTMLTextExtractor;
34  
35  import java.io.BufferedInputStream;
36  import java.io.BufferedReader;
37  import java.io.BufferedWriter;
38  import java.io.File;
39  import java.io.FileInputStream;
40  import java.io.FileOutputStream;
41  import java.io.FileReader;
42  import java.io.IOException;
43  import java.io.InputStream;
44  import java.io.OutputStreamWriter;
45  import java.io.Reader;
46  
47  import java.nio.channels.FileChannel;
48  
49  import java.util.ArrayList;
50  import java.util.Arrays;
51  import java.util.List;
52  import java.util.Properties;
53  
54  import org.apache.jackrabbit.extractor.MsExcelTextExtractor;
55  import org.apache.jackrabbit.extractor.MsPowerPointTextExtractor;
56  import org.apache.jackrabbit.extractor.MsWordTextExtractor;
57  import org.apache.jackrabbit.extractor.OpenOfficeTextExtractor;
58  import org.apache.jackrabbit.extractor.PdfTextExtractor;
59  import org.apache.jackrabbit.extractor.PlainTextExtractor;
60  import org.apache.jackrabbit.extractor.RTFTextExtractor;
61  import org.apache.jackrabbit.extractor.TextExtractor;
62  import org.apache.jackrabbit.extractor.XMLTextExtractor;
63  
64  import org.mozilla.intl.chardet.nsDetector;
65  import org.mozilla.intl.chardet.nsPSMDetector;
66  
67  /**
68   * <a href="FileImpl.java.html"><b><i>View Source</i></b></a>
69   *
70   * @author Brian Wing Shun Chan
71   * @author Alexander Chow
72   *
73   */
74  public class FileImpl implements com.liferay.portal.kernel.util.File {
75  
76      public static FileImpl getInstance() {
77          return _instance;
78      }
79  
80      public void copyDirectory(String sourceDirName, String destinationDirName) {
81          copyDirectory(new File(sourceDirName), new File(destinationDirName));
82      }
83  
84      public void copyDirectory(File source, File destination) {
85          if (source.exists() && source.isDirectory()) {
86              if (!destination.exists()) {
87                  destination.mkdirs();
88              }
89  
90              File[] fileArray = source.listFiles();
91  
92              for (int i = 0; i < fileArray.length; i++) {
93                  if (fileArray[i].isDirectory()) {
94                      copyDirectory(
95                          fileArray[i],
96                          new File(destination.getPath() + File.separator
97                              + fileArray[i].getName()));
98                  }
99                  else {
100                     copyFile(
101                         fileArray[i],
102                         new File(destination.getPath() + File.separator
103                             + fileArray[i].getName()));
104                 }
105             }
106         }
107     }
108 
109     public void copyFile(String source, String destination) {
110         copyFile(source, destination, false);
111     }
112 
113     public void copyFile(String source, String destination, boolean lazy) {
114         copyFile(new File(source), new File(destination), lazy);
115     }
116 
117     public void copyFile(File source, File destination) {
118         copyFile(source, destination, false);
119     }
120 
121     public void copyFile(File source, File destination, boolean lazy) {
122         if (!source.exists()) {
123             return;
124         }
125 
126         if (lazy) {
127             String oldContent = null;
128 
129             try {
130                 oldContent = read(source);
131             }
132             catch (Exception e) {
133                 return;
134             }
135 
136             String newContent = null;
137 
138             try {
139                 newContent = read(destination);
140             }
141             catch (Exception e) {
142             }
143 
144             if ((oldContent == null) || !oldContent.equals(newContent)) {
145                 copyFile(source, destination, false);
146             }
147         }
148         else {
149             if ((destination.getParentFile() != null) &&
150                 (!destination.getParentFile().exists())) {
151 
152                 destination.getParentFile().mkdirs();
153             }
154 
155             try {
156                 FileChannel srcChannel =
157                     new FileInputStream(source).getChannel();
158                 FileChannel dstChannel =
159                     new FileOutputStream(destination).getChannel();
160 
161                 dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
162 
163                 srcChannel.close();
164                 dstChannel.close();
165             }
166             catch (IOException ioe) {
167                 _log.error(ioe.getMessage());
168             }
169         }
170     }
171 
172     public File createTempFile() {
173         return createTempFile(null);
174     }
175 
176     public File createTempFile(String extension) {
177         return new File(createTempFileName(extension));
178     }
179 
180     public String createTempFileName() {
181         return createTempFileName(null);
182     }
183 
184     public String createTempFileName(String extension) {
185         StringBuilder sb = new StringBuilder();
186 
187         sb.append(SystemProperties.get(SystemProperties.TMP_DIR));
188         sb.append(StringPool.SLASH);
189         sb.append(Time.getTimestamp());
190         sb.append(PwdGenerator.getPassword(PwdGenerator.KEY2, 8));
191 
192         if (Validator.isNotNull(extension)) {
193             sb.append(StringPool.PERIOD);
194             sb.append(extension);
195         }
196 
197         return sb.toString();
198     }
199 
200     public boolean delete(String file) {
201         return delete(new File(file));
202     }
203 
204     public boolean delete(File file) {
205         if ((file != null) && file.exists()) {
206             return file.delete();
207         }
208         else {
209             return false;
210         }
211     }
212 
213     public void deltree(String directory) {
214         deltree(new File(directory));
215     }
216 
217     public void deltree(File directory) {
218         if (directory.exists() && directory.isDirectory()) {
219             File[] fileArray = directory.listFiles();
220 
221             for (int i = 0; i < fileArray.length; i++) {
222                 if (fileArray[i].isDirectory()) {
223                     deltree(fileArray[i]);
224                 }
225                 else {
226                     fileArray[i].delete();
227                 }
228             }
229 
230             directory.delete();
231         }
232     }
233 
234     public boolean exists(String fileName) {
235         return exists(new File(fileName));
236     }
237 
238     public boolean exists(File file) {
239         return file.exists();
240     }
241 
242     public String extractText(InputStream is, String fileExt) {
243         String text = null;
244 
245         try {
246             fileExt = GetterUtil.getString(fileExt).toLowerCase();
247 
248             TextExtractor extractor = null;
249 
250             String contentType = null;
251             String encoding = System.getProperty("encoding");
252 
253             if (fileExt.equals(".doc")) {
254                 extractor = new MsWordTextExtractor();
255 
256                 contentType = "application/vnd.ms-word";
257             }
258             else if (fileExt.equals(".htm") || fileExt.equals(".html")) {
259                 extractor = new JerichoHTMLTextExtractor();
260 
261                 contentType = "text/html";
262             }
263             else if (fileExt.equals(".odb") || fileExt.equals(".odf") ||
264                      fileExt.equals(".odg") || fileExt.equals(".odp") ||
265                      fileExt.equals(".ods") || fileExt.equals(".odt")) {
266 
267                 extractor = new OpenOfficeTextExtractor();
268 
269                 contentType = "application/vnd.oasis.opendocument.";
270 
271                 if (fileExt.equals(".odb")) {
272                     contentType += "database";
273                 }
274                 else if (fileExt.equals(".odf")) {
275                     contentType += "formula";
276                 }
277                 else if (fileExt.equals(".odg")) {
278                     contentType += "graphics";
279                 }
280                 else if (fileExt.equals(".odp")) {
281                     contentType += "presentation";
282                 }
283                 else if (fileExt.equals(".ods")) {
284                     contentType += "spreadsheet";
285                 }
286                 else if (fileExt.equals(".odt")) {
287                     contentType += "text";
288                 }
289             }
290             else if (fileExt.equals(".pdf")) {
291                 extractor = new PdfTextExtractor();
292 
293                 contentType = "application/pdf";
294             }
295             else if (fileExt.equals(".ppt")) {
296                 extractor = new MsPowerPointTextExtractor();
297 
298                 contentType = "application/vnd.ms-powerpoint";
299             }
300             else if (fileExt.equals(".rtf")) {
301                 extractor = new RTFTextExtractor();
302 
303                 contentType = "application/rtf";
304             }
305             else if (fileExt.equals(".txt")) {
306                 extractor = new PlainTextExtractor();
307 
308                 contentType = "text/plain";
309             }
310             else if (fileExt.equals(".xls")) {
311                 extractor = new MsExcelTextExtractor();
312 
313                 contentType = "application/vnd.ms-excel";
314             }
315             else if (fileExt.equals(".xml")) {
316                 extractor = new XMLTextExtractor();
317 
318                 contentType = "text/xml";
319             }
320 
321             if (extractor != null) {
322                 if (_log.isInfoEnabled()) {
323                     _log.info(
324                         "Using extractor " + extractor.getClass().getName() +
325                             " for extension " + fileExt);
326                 }
327 
328                 StringBuilder sb = new StringBuilder();
329 
330                 BufferedReader reader = new BufferedReader(
331                     extractor.extractText(is, contentType, encoding));
332 
333                 int i;
334 
335                 while ((i = reader.read()) != -1) {
336                     sb.append((char)i);
337                 }
338 
339                 reader.close();
340 
341                 text = sb.toString();
342             }
343             else {
344                 if (_log.isInfoEnabled()) {
345                     _log.info("No extractor found for extension " + fileExt);
346                 }
347             }
348         }
349         catch (Exception e) {
350             _log.error(e);
351         }
352 
353         if (_log.isDebugEnabled()) {
354             _log.debug("Extractor returned text:\n\n" + text);
355         }
356 
357         if (text == null) {
358             text = StringPool.BLANK;
359         }
360 
361         return text;
362     }
363 
364     public String getAbsolutePath(File file) {
365         return StringUtil.replace(
366             file.getAbsolutePath(), StringPool.BACK_SLASH, StringPool.SLASH);
367     }
368 
369     public byte[] getBytes(File file) throws IOException {
370         if ((file == null) || !file.exists()) {
371             return null;
372         }
373 
374         FileInputStream is = new FileInputStream(file);
375 
376         byte[] bytes = getBytes(is, (int)file.length());
377 
378         is.close();
379 
380         return bytes;
381     }
382 
383     public byte[] getBytes(InputStream is) throws IOException {
384         return getBytes(is, -1);
385     }
386 
387     public byte[] getBytes(InputStream is, int bufferSize) throws IOException {
388         ByteArrayMaker bam = null;
389 
390         if (bufferSize <= 0) {
391             bam = new ByteArrayMaker();
392         }
393         else {
394             bam = new ByteArrayMaker(bufferSize);
395         }
396 
397         boolean createBuffered = false;
398 
399         try {
400             if (!(is instanceof BufferedInputStream)) {
401                 is = new BufferedInputStream(is);
402 
403                 createBuffered = true;
404             }
405 
406             int c = is.read();
407 
408             while (c != -1) {
409                 bam.write(c);
410 
411                 c = is.read();
412             }
413         }
414         finally {
415             if (createBuffered) {
416                 is.close();
417             }
418         }
419 
420         bam.close();
421 
422         return bam.toByteArray();
423     }
424 
425     public String getExtension(String fileName) {
426         if (fileName == null) {
427             return null;
428         }
429 
430         int pos = fileName.lastIndexOf(StringPool.PERIOD);
431 
432         if (pos != -1) {
433             return fileName.substring(pos + 1, fileName.length()).toLowerCase();
434         }
435         else {
436             return null;
437         }
438     }
439 
440     public String getPath(String fullFileName) {
441         int pos = fullFileName.lastIndexOf(StringPool.SLASH);
442 
443         if (pos == -1) {
444             pos = fullFileName.lastIndexOf(StringPool.BACK_SLASH);
445         }
446 
447         String shortFileName = fullFileName.substring(0, pos);
448 
449         if (Validator.isNull(shortFileName)) {
450             return StringPool.SLASH;
451         }
452 
453         return shortFileName;
454     }
455 
456     public String getShortFileName(String fullFileName) {
457         int pos = fullFileName.lastIndexOf(StringPool.SLASH);
458 
459         if (pos == -1) {
460             pos = fullFileName.lastIndexOf(StringPool.BACK_SLASH);
461         }
462 
463         String shortFileName =
464             fullFileName.substring(pos + 1, fullFileName.length());
465 
466         return shortFileName;
467     }
468 
469     public boolean isAscii(File file) throws IOException {
470         boolean ascii = true;
471 
472         nsDetector detector = new nsDetector(nsPSMDetector.ALL);
473 
474         BufferedInputStream bis = new BufferedInputStream(
475             new FileInputStream(file));
476 
477         byte[] buffer = new byte[1024];
478 
479         int len = 0;
480 
481         while ((len = bis.read(buffer, 0, buffer.length)) != -1) {
482             if (ascii) {
483                 ascii = detector.isAscii(buffer, len);
484 
485                 if (!ascii) {
486                     break;
487                 }
488             }
489         }
490 
491         detector.DataEnd();
492 
493         return ascii;
494     }
495 
496     public String[] listDirs(String fileName) {
497         return listDirs(new File(fileName));
498     }
499 
500     public String[] listDirs(File file) {
501         List<String> dirs = new ArrayList<String>();
502 
503         File[] fileArray = file.listFiles();
504 
505         for (int i = 0; (fileArray != null) && (i < fileArray.length); i++) {
506             if (fileArray[i].isDirectory()) {
507                 dirs.add(fileArray[i].getName());
508             }
509         }
510 
511         return dirs.toArray(new String[dirs.size()]);
512     }
513 
514     public String[] listFiles(String fileName) {
515         if (Validator.isNull(fileName)) {
516             return new String[0];
517         }
518 
519         return listFiles(new File(fileName));
520     }
521 
522     public String[] listFiles(File file) {
523         List<String> files = new ArrayList<String>();
524 
525         File[] fileArray = file.listFiles();
526 
527         for (int i = 0; (fileArray != null) && (i < fileArray.length); i++) {
528             if (fileArray[i].isFile()) {
529                 files.add(fileArray[i].getName());
530             }
531         }
532 
533         return files.toArray(new String[files.size()]);
534     }
535 
536     public void mkdirs(String pathName) {
537         File file = new File(pathName);
538 
539         file.mkdirs();
540     }
541 
542     public boolean move(String sourceFileName, String destinationFileName) {
543         return move(new File(sourceFileName), new File(destinationFileName));
544     }
545 
546     public boolean move(File source, File destination) {
547         if (!source.exists()) {
548             return false;
549         }
550 
551         destination.delete();
552 
553         return source.renameTo(destination);
554     }
555 
556     public String read(String fileName) throws IOException {
557         return read(new File(fileName));
558     }
559 
560     public String read(File file) throws IOException {
561         return read(file, false);
562     }
563 
564     public String read(File file, boolean raw) throws IOException {
565         FileInputStream fis = new FileInputStream(file);
566 
567         byte[] bytes = new byte[fis.available()];
568 
569         fis.read(bytes);
570 
571         fis.close();
572 
573         String s = new String(bytes, StringPool.UTF8);
574 
575         if (raw) {
576             return s;
577         }
578         else {
579             return StringUtil.replace(
580                 s, StringPool.RETURN_NEW_LINE, StringPool.NEW_LINE);
581         }
582     }
583 
584     public String replaceSeparator(String fileName) {
585         return StringUtil.replace(
586             fileName, StringPool.BACK_SLASH, StringPool.SLASH);
587     }
588 
589     public File[] sortFiles(File[] files) {
590         if (files == null) {
591             return null;
592         }
593 
594         Arrays.sort(files, new FileComparator());
595 
596         List<File> directoryList = new ArrayList<File>();
597         List<File> fileList = new ArrayList<File>();
598 
599         for (int i = 0; i < files.length; i++) {
600             if (files[i].isDirectory()) {
601                 directoryList.add(files[i]);
602             }
603             else {
604                 fileList.add(files[i]);
605             }
606         }
607 
608         directoryList.addAll(fileList);
609 
610         return directoryList.toArray(new File[directoryList.size()]);
611     }
612 
613     public String stripExtension(String fileName) {
614         if (fileName == null) {
615             return null;
616         }
617 
618         int pos = fileName.lastIndexOf(StringPool.PERIOD);
619 
620         if (pos != -1) {
621             return fileName.substring(0, pos);
622         }
623         else {
624             return fileName;
625         }
626     }
627 
628     public List<String> toList(Reader reader) {
629         List<String> list = new ArrayList<String>();
630 
631         try {
632             BufferedReader br = new BufferedReader(reader);
633 
634             String line = null;
635 
636             while ((line = br.readLine()) != null) {
637                 list.add(line);
638             }
639 
640             br.close();
641         }
642         catch (IOException ioe) {
643         }
644 
645         return list;
646     }
647 
648     public List<String> toList(String fileName) {
649         try {
650             return toList(new FileReader(fileName));
651         }
652         catch (IOException ioe) {
653             return new ArrayList<String>();
654         }
655     }
656 
657     public Properties toProperties(FileInputStream fis) {
658         Properties props = new Properties();
659 
660         try {
661             props.load(fis);
662         }
663         catch (IOException ioe) {
664         }
665 
666         return props;
667     }
668 
669     public Properties toProperties(String fileName) {
670         try {
671             return toProperties(new FileInputStream(fileName));
672         }
673         catch (IOException ioe) {
674             return new Properties();
675         }
676     }
677 
678     public void write(String fileName, String s) throws IOException {
679         write(new File(fileName), s);
680     }
681 
682     public void write(String fileName, String s, boolean lazy)
683         throws IOException {
684 
685         write(new File(fileName), s, lazy);
686     }
687 
688     public void write(String fileName, String s, boolean lazy, boolean append)
689         throws IOException {
690 
691         write(new File(fileName), s, lazy, append);
692     }
693 
694     public void write(String pathName, String fileName, String s)
695         throws IOException {
696 
697         write(new File(pathName, fileName), s);
698     }
699 
700     public void write(String pathName, String fileName, String s, boolean lazy)
701         throws IOException {
702 
703         write(new File(pathName, fileName), s, lazy);
704     }
705 
706     public void write(
707             String pathName, String fileName, String s, boolean lazy,
708             boolean append)
709         throws IOException {
710 
711         write(new File(pathName, fileName), s, lazy, append);
712     }
713 
714     public void write(File file, String s) throws IOException {
715         write(file, s, false);
716     }
717 
718     public void write(File file, String s, boolean lazy)
719         throws IOException {
720 
721         write(file, s, lazy, false);
722     }
723 
724     public void write(File file, String s, boolean lazy, boolean append)
725         throws IOException {
726 
727         if (file.getParent() != null) {
728             mkdirs(file.getParent());
729         }
730 
731         if (lazy && file.exists()) {
732             String content = read(file);
733 
734             if (content.equals(s)) {
735                 return;
736             }
737         }
738 
739         BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
740             new FileOutputStream(file, append), StringPool.UTF8));
741 
742         bw.write(s);
743 
744         bw.close();
745     }
746 
747     public void write(String fileName, byte[] bytes) throws IOException {
748         write(new File(fileName), bytes);
749     }
750 
751     public void write(File file, byte[] bytes) throws IOException {
752         if (file.getParent() != null) {
753             mkdirs(file.getParent());
754         }
755 
756         FileOutputStream fos = new FileOutputStream(file);
757 
758         fos.write(bytes);
759 
760         fos.close();
761     }
762 
763     public void write(String fileName, InputStream is) throws IOException {
764         write(fileName, getBytes(is));
765     }
766 
767     public void write(File file, InputStream is) throws IOException {
768         write(file, getBytes(is));
769     }
770 
771     private static Log _log = LogFactoryUtil.getLog(FileImpl.class);
772 
773     private static FileImpl _instance = new FileImpl();
774 
775 }