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