001
014
015 package com.liferay.portal.util;
016
017 import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
018 import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
019 import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
020 import com.liferay.portal.kernel.log.Log;
021 import com.liferay.portal.kernel.log.LogFactoryUtil;
022 import com.liferay.portal.kernel.nio.charset.CharsetEncoderUtil;
023 import com.liferay.portal.kernel.process.ClassPathUtil;
024 import com.liferay.portal.kernel.process.ProcessCallable;
025 import com.liferay.portal.kernel.process.ProcessException;
026 import com.liferay.portal.kernel.process.ProcessExecutor;
027 import com.liferay.portal.kernel.util.ArrayUtil;
028 import com.liferay.portal.kernel.util.CharPool;
029 import com.liferay.portal.kernel.util.FileComparator;
030 import com.liferay.portal.kernel.util.StreamUtil;
031 import com.liferay.portal.kernel.util.StringBundler;
032 import com.liferay.portal.kernel.util.StringPool;
033 import com.liferay.portal.kernel.util.StringUtil;
034 import com.liferay.portal.kernel.util.SystemProperties;
035 import com.liferay.portal.kernel.util.Time;
036 import com.liferay.portal.kernel.util.Validator;
037 import com.liferay.util.PwdGenerator;
038 import com.liferay.util.ant.ExpandTask;
039
040 import java.io.File;
041 import java.io.FileInputStream;
042 import java.io.FileOutputStream;
043 import java.io.FileReader;
044 import java.io.IOException;
045 import java.io.InputStream;
046 import java.io.OutputStreamWriter;
047 import java.io.RandomAccessFile;
048 import java.io.Reader;
049 import java.io.Writer;
050
051 import java.nio.ByteBuffer;
052 import java.nio.channels.FileChannel;
053
054 import java.util.ArrayList;
055 import java.util.Arrays;
056 import java.util.List;
057 import java.util.Properties;
058
059 import org.apache.commons.io.FileUtils;
060 import org.apache.tika.Tika;
061 import org.apache.tools.ant.DirectoryScanner;
062
063 import org.mozilla.intl.chardet.nsDetector;
064 import org.mozilla.intl.chardet.nsPSMDetector;
065
066
070 public class FileImpl implements com.liferay.portal.kernel.util.File {
071
072 public static FileImpl getInstance() {
073 return _instance;
074 }
075
076 public void copyDirectory(File source, File destination)
077 throws IOException {
078
079 if (source.exists() && source.isDirectory()) {
080 if (!destination.exists()) {
081 destination.mkdirs();
082 }
083
084 File[] fileArray = source.listFiles();
085
086 for (int i = 0; i < fileArray.length; i++) {
087 if (fileArray[i].isDirectory()) {
088 copyDirectory(
089 fileArray[i],
090 new File(destination.getPath() + File.separator
091 + fileArray[i].getName()));
092 }
093 else {
094 copyFile(
095 fileArray[i],
096 new File(destination.getPath() + File.separator
097 + fileArray[i].getName()));
098 }
099 }
100 }
101 }
102
103 public void copyDirectory(String sourceDirName, String destinationDirName)
104 throws IOException {
105
106 copyDirectory(new File(sourceDirName), new File(destinationDirName));
107 }
108
109 public void copyFile(File source, File destination) throws IOException {
110 copyFile(source, destination, false);
111 }
112
113 public void copyFile(File source, File destination, boolean lazy)
114 throws IOException {
115
116 if (!source.exists()) {
117 return;
118 }
119
120 if (lazy) {
121 String oldContent = null;
122
123 try {
124 oldContent = read(source);
125 }
126 catch (Exception e) {
127 return;
128 }
129
130 String newContent = null;
131
132 try {
133 newContent = read(destination);
134 }
135 catch (Exception e) {
136 }
137
138 if ((oldContent == null) || !oldContent.equals(newContent)) {
139 copyFile(source, destination, false);
140 }
141 }
142 else {
143 if ((destination.getParentFile() != null) &&
144 (!destination.getParentFile().exists())) {
145
146 destination.getParentFile().mkdirs();
147 }
148
149 StreamUtil.transfer(
150 new FileInputStream(source), new FileOutputStream(destination));
151 }
152 }
153
154 public void copyFile(String source, String destination) throws IOException {
155 copyFile(source, destination, false);
156 }
157
158 public void copyFile(String source, String destination, boolean lazy)
159 throws IOException {
160
161 copyFile(new File(source), new File(destination), lazy);
162 }
163
164 public File createTempFile() {
165 return createTempFile(StringPool.BLANK);
166 }
167
168 public File createTempFile(byte[] bytes) throws IOException {
169 File file = createTempFile(StringPool.BLANK);
170
171 write(file, bytes);
172
173 return file;
174 }
175
176 public File createTempFile(InputStream is) throws IOException {
177 File file = createTempFile(StringPool.BLANK);
178
179 write(file, is);
180
181 return file;
182 }
183
184 public File createTempFile(String extension) {
185 return new File(createTempFileName(extension));
186 }
187
188 public String createTempFileName() {
189 return createTempFileName(null);
190 }
191
192 public String createTempFileName(String extension) {
193 StringBundler sb = new StringBundler();
194
195 sb.append(SystemProperties.get(SystemProperties.TMP_DIR));
196 sb.append(StringPool.SLASH);
197 sb.append(Time.getTimestamp());
198 sb.append(PwdGenerator.getPassword(PwdGenerator.KEY2, 8));
199
200 if (Validator.isNotNull(extension)) {
201 sb.append(StringPool.PERIOD);
202 sb.append(extension);
203 }
204
205 return sb.toString();
206 }
207
208 public String decodeSafeFileName(String fileName) {
209 return StringUtil.replace(
210 fileName, _SAFE_FILE_NAME_2, _SAFE_FILE_NAME_1);
211 }
212
213 public boolean delete(File file) {
214 if ((file != null) && file.exists()) {
215 return file.delete();
216 }
217 else {
218 return false;
219 }
220 }
221
222 public boolean delete(String file) {
223 return delete(new File(file));
224 }
225
226 public void deltree(File directory) {
227 if (directory.exists() && directory.isDirectory()) {
228 File[] fileArray = directory.listFiles();
229
230 for (int i = 0; i < fileArray.length; i++) {
231 if (fileArray[i].isDirectory()) {
232 deltree(fileArray[i]);
233 }
234 else {
235 fileArray[i].delete();
236 }
237 }
238
239 directory.delete();
240 }
241 }
242
243 public void deltree(String directory) {
244 deltree(new File(directory));
245 }
246
247 public String encodeSafeFileName(String fileName) {
248 if (fileName == null) {
249 return StringPool.BLANK;
250 }
251
252 return StringUtil.replace(
253 fileName, _SAFE_FILE_NAME_1, _SAFE_FILE_NAME_2);
254 }
255
256 public boolean exists(File file) {
257 return file.exists();
258 }
259
260 public boolean exists(String fileName) {
261 return exists(new File(fileName));
262 }
263
264 public String extractText(InputStream is, String fileName) {
265 String text = null;
266
267 try {
268 Tika tika = new Tika();
269
270 boolean forkProcess = false;
271
272 if (PropsValues.TEXT_EXTRACTION_FORK_PROCESS_ENABLED) {
273 String mimeType = tika.detect(is);
274
275 if (ArrayUtil.contains(
276 PropsValues.TEXT_EXTRACTION_FORK_PROCESS_MIME_TYPES,
277 mimeType)) {
278
279 forkProcess = true;
280 }
281 }
282
283 if (forkProcess) {
284 text = ProcessExecutor.execute(
285 new ExtractTextProcessCallable(getBytes(is)),
286 ClassPathUtil.getPortalClassPath());
287 }
288 else {
289 text = tika.parseToString(is);
290 }
291 }
292 catch (Exception e) {
293 _log.error(e, e);
294 }
295
296 if (_log.isInfoEnabled()) {
297 if (text == null) {
298 _log.info("Text extraction failed for " + fileName);
299 }
300 else {
301 _log.info("Text was extracted for " + fileName);
302 }
303 }
304
305 if (_log.isDebugEnabled()) {
306 _log.debug("Extractor returned text:\n\n" + text);
307 }
308
309 if (text == null) {
310 text = StringPool.BLANK;
311 }
312
313 return text;
314 }
315
316 public String[] find(String directory, String includes, String excludes) {
317 if (directory.length() > 0) {
318 directory = replaceSeparator(directory);
319
320 if (directory.charAt(directory.length() - 1) == CharPool.SLASH) {
321 directory = directory.substring(0, directory.length() - 1);
322 }
323 }
324
325 DirectoryScanner directoryScanner = new DirectoryScanner();
326
327 directoryScanner.setBasedir(directory);
328 directoryScanner.setExcludes(StringUtil.split(excludes));
329 directoryScanner.setIncludes(StringUtil.split(includes));
330
331 directoryScanner.scan();
332
333 String[] includedFiles = directoryScanner.getIncludedFiles();
334
335 for (int i = 0; i < includedFiles.length; i++) {
336 includedFiles[i] =
337 directory.concat(StringPool.SLASH).concat(
338 replaceSeparator(includedFiles[i]));
339 }
340
341 return includedFiles;
342 }
343
344 public String getAbsolutePath(File file) {
345 return StringUtil.replace(
346 file.getAbsolutePath(), CharPool.BACK_SLASH, CharPool.SLASH);
347 }
348
349 public byte[] getBytes(File file) throws IOException {
350 if ((file == null) || !file.exists()) {
351 return null;
352 }
353
354 RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
355
356 byte[] bytes = new byte[(int)randomAccessFile.length()];
357
358 randomAccessFile.readFully(bytes);
359
360 randomAccessFile.close();
361
362 return bytes;
363 }
364
365 public byte[] getBytes(InputStream is) throws IOException {
366 return getBytes(is, -1);
367 }
368
369 public byte[] getBytes(InputStream inputStream, int bufferSize)
370 throws IOException {
371
372 return getBytes(inputStream, bufferSize, true);
373 }
374
375 public byte[] getBytes(
376 InputStream inputStream, int bufferSize, boolean cleanUpStream)
377 throws IOException {
378
379 if (inputStream == null) {
380 return null;
381 }
382
383 UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
384 new UnsyncByteArrayOutputStream();
385
386 StreamUtil.transfer(
387 inputStream, unsyncByteArrayOutputStream, bufferSize,
388 cleanUpStream);
389
390 return unsyncByteArrayOutputStream.toByteArray();
391 }
392
393 public String getExtension(String fileName) {
394 if (fileName == null) {
395 return null;
396 }
397
398 int pos = fileName.lastIndexOf(CharPool.PERIOD);
399
400 if (pos > 0) {
401 return fileName.substring(pos + 1, fileName.length()).toLowerCase();
402 }
403 else {
404 return StringPool.BLANK;
405 }
406 }
407
408 public String getPath(String fullFileName) {
409 int pos = fullFileName.lastIndexOf(CharPool.SLASH);
410
411 if (pos == -1) {
412 pos = fullFileName.lastIndexOf(CharPool.BACK_SLASH);
413 }
414
415 String shortFileName = fullFileName.substring(0, pos);
416
417 if (Validator.isNull(shortFileName)) {
418 return StringPool.SLASH;
419 }
420
421 return shortFileName;
422 }
423
424 public String getShortFileName(String fullFileName) {
425 int pos = fullFileName.lastIndexOf(CharPool.SLASH);
426
427 if (pos == -1) {
428 pos = fullFileName.lastIndexOf(CharPool.BACK_SLASH);
429 }
430
431 String shortFileName =
432 fullFileName.substring(pos + 1, fullFileName.length());
433
434 return shortFileName;
435 }
436
437 public boolean isAscii(File file) throws IOException {
438 boolean ascii = true;
439
440 nsDetector detector = new nsDetector(nsPSMDetector.ALL);
441
442 InputStream inputStream = new FileInputStream(file);
443
444 byte[] buffer = new byte[1024];
445
446 int len = 0;
447
448 while ((len = inputStream.read(buffer, 0, buffer.length)) != -1) {
449 if (ascii) {
450 ascii = detector.isAscii(buffer, len);
451
452 if (!ascii) {
453 break;
454 }
455 }
456 }
457
458 detector.DataEnd();
459
460 inputStream.close();
461
462 return ascii;
463 }
464
465 public boolean isSameContent(File file, byte[] bytes, int length) {
466 FileChannel fileChannel = null;
467
468 try {
469 FileInputStream fileInputStream = new FileInputStream(file);
470
471 fileChannel = fileInputStream.getChannel();
472
473 if (fileChannel.size() != length) {
474 return false;
475 }
476
477 byte[] buffer = new byte[1024];
478
479 ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
480
481 int bufferIndex = 0;
482 int bufferLength = -1;
483
484 while (((bufferLength = fileChannel.read(byteBuffer)) > 0) &&
485 (bufferIndex < length)) {
486
487 for (int i = 0; i < bufferLength; i++) {
488 if (buffer[i] != bytes[bufferIndex++]) {
489 return false;
490 }
491 }
492
493 byteBuffer.clear();
494 }
495
496 if ((bufferIndex != length) || (bufferLength != -1)) {
497 return false;
498 }
499 else {
500 return true;
501 }
502 }
503 catch (Exception e) {
504 return false;
505 }
506 finally {
507 if (fileChannel != null) {
508 try {
509 fileChannel.close();
510 }
511 catch (IOException ioe) {
512 }
513 }
514 }
515 }
516
517 public boolean isSameContent(File file, String s) {
518 ByteBuffer byteBuffer = CharsetEncoderUtil.encode(StringPool.UTF8, s);
519
520 return isSameContent(file, byteBuffer.array(), byteBuffer.limit());
521 }
522
523 public String[] listDirs(File file) {
524 List<String> dirs = new ArrayList<String>();
525
526 File[] fileArray = file.listFiles();
527
528 for (int i = 0; (fileArray != null) && (i < fileArray.length); i++) {
529 if (fileArray[i].isDirectory()) {
530 dirs.add(fileArray[i].getName());
531 }
532 }
533
534 return dirs.toArray(new String[dirs.size()]);
535 }
536
537 public String[] listDirs(String fileName) {
538 return listDirs(new File(fileName));
539 }
540
541 public String[] listFiles(File file) {
542 List<String> files = new ArrayList<String>();
543
544 File[] fileArray = file.listFiles();
545
546 for (int i = 0; (fileArray != null) && (i < fileArray.length); i++) {
547 if (fileArray[i].isFile()) {
548 files.add(fileArray[i].getName());
549 }
550 }
551
552 return files.toArray(new String[files.size()]);
553 }
554
555 public String[] listFiles(String fileName) {
556 if (Validator.isNull(fileName)) {
557 return new String[0];
558 }
559
560 return listFiles(new File(fileName));
561 }
562
563 public void mkdirs(String pathName) {
564 File file = new File(pathName);
565
566 file.mkdirs();
567 }
568
569 public boolean move(File source, File destination) {
570 if (!source.exists()) {
571 return false;
572 }
573
574 destination.delete();
575
576 return source.renameTo(destination);
577 }
578
579 public boolean move(String sourceFileName, String destinationFileName) {
580 return move(new File(sourceFileName), new File(destinationFileName));
581 }
582
583 public String read(File file) throws IOException {
584 return read(file, false);
585 }
586
587 public String read(File file, boolean raw) throws IOException {
588 byte[] bytes = getBytes(file);
589
590 if (bytes == null) {
591 return null;
592 }
593
594 String s = new String(bytes, StringPool.UTF8);
595
596 if (raw) {
597 return s;
598 }
599 else {
600 return StringUtil.replace(
601 s, StringPool.RETURN_NEW_LINE, StringPool.NEW_LINE);
602 }
603 }
604
605 public String read(String fileName) throws IOException {
606 return read(new File(fileName));
607 }
608
609 public String replaceSeparator(String fileName) {
610 return StringUtil.replace(
611 fileName, CharPool.BACK_SLASH, CharPool.SLASH);
612 }
613
614 public File[] sortFiles(File[] files) {
615 if (files == null) {
616 return null;
617 }
618
619 Arrays.sort(files, new FileComparator());
620
621 List<File> directoryList = new ArrayList<File>();
622 List<File> fileList = new ArrayList<File>();
623
624 for (int i = 0; i < files.length; i++) {
625 if (files[i].isDirectory()) {
626 directoryList.add(files[i]);
627 }
628 else {
629 fileList.add(files[i]);
630 }
631 }
632
633 directoryList.addAll(fileList);
634
635 return directoryList.toArray(new File[directoryList.size()]);
636 }
637
638 public String stripExtension(String fileName) {
639 if (fileName == null) {
640 return null;
641 }
642
643 String ext = getExtension(fileName);
644
645 if (ext.length() > 0) {
646 return fileName.substring(0, fileName.length() - ext.length() - 1);
647 }
648 else {
649 return fileName;
650 }
651 }
652
653 public List<String> toList(Reader reader) {
654 List<String> list = new ArrayList<String>();
655
656 try {
657 UnsyncBufferedReader unsyncBufferedReader =
658 new UnsyncBufferedReader(reader);
659
660 String line = null;
661
662 while ((line = unsyncBufferedReader.readLine()) != null) {
663 list.add(line);
664 }
665
666 unsyncBufferedReader.close();
667 }
668 catch (IOException ioe) {
669 }
670
671 return list;
672 }
673
674 public List<String> toList(String fileName) {
675 try {
676 return toList(new FileReader(fileName));
677 }
678 catch (IOException ioe) {
679 return new ArrayList<String>();
680 }
681 }
682
683 public Properties toProperties(FileInputStream fis) {
684 Properties properties = new Properties();
685
686 try {
687 properties.load(fis);
688 }
689 catch (IOException ioe) {
690 }
691
692 return properties;
693 }
694
695 public Properties toProperties(String fileName) {
696 try {
697 return toProperties(new FileInputStream(fileName));
698 }
699 catch (IOException ioe) {
700 return new Properties();
701 }
702 }
703
704 public void touch(File file) throws IOException {
705 FileUtils.touch(file);
706 }
707
708 public void touch(String fileName) throws IOException {
709 touch(new File(fileName));
710 }
711
712 public void unzip(File source, File destination) {
713 ExpandTask.expand(source, destination);
714 }
715
716 public void write(File file, byte[] bytes) throws IOException {
717 write(file, bytes, 0, bytes.length);
718 }
719
720 public void write(File file, byte[] bytes, int offset, int length)
721 throws IOException {
722
723 if (file.getParent() != null) {
724 mkdirs(file.getParent());
725 }
726
727 FileOutputStream fos = new FileOutputStream(file);
728
729 fos.write(bytes, offset, length);
730
731 fos.close();
732 }
733
734 public void write(File file, InputStream is) throws IOException {
735 if (file.getParent() != null) {
736 mkdirs(file.getParent());
737 }
738
739 StreamUtil.transfer(is, new FileOutputStream(file));
740 }
741
742 public void write(File file, String s) throws IOException {
743 write(file, s, false);
744 }
745
746 public void write(File file, String s, boolean lazy)
747 throws IOException {
748
749 write(file, s, lazy, false);
750 }
751
752 public void write(File file, String s, boolean lazy, boolean append)
753 throws IOException {
754
755 if (file.getParent() != null) {
756 mkdirs(file.getParent());
757 }
758
759 if (lazy && file.exists()) {
760 String content = read(file);
761
762 if (content.equals(s)) {
763 return;
764 }
765 }
766
767 Writer writer = new OutputStreamWriter(
768 new FileOutputStream(file, append), StringPool.UTF8);
769
770 writer.write(s);
771
772 writer.close();
773 }
774
775 public void write(String fileName, byte[] bytes) throws IOException {
776 write(new File(fileName), bytes);
777 }
778
779 public void write(String fileName, InputStream is) throws IOException {
780 write(new File(fileName), is);
781 }
782
783 public void write(String fileName, String s) throws IOException {
784 write(new File(fileName), s);
785 }
786
787 public void write(String fileName, String s, boolean lazy)
788 throws IOException {
789
790 write(new File(fileName), s, lazy);
791 }
792
793 public void write(String fileName, String s, boolean lazy, boolean append)
794 throws IOException {
795
796 write(new File(fileName), s, lazy, append);
797 }
798
799 public void write(String pathName, String fileName, String s)
800 throws IOException {
801
802 write(new File(pathName, fileName), s);
803 }
804
805 public void write(String pathName, String fileName, String s, boolean lazy)
806 throws IOException {
807
808 write(new File(pathName, fileName), s, lazy);
809 }
810
811 public void write(
812 String pathName, String fileName, String s, boolean lazy,
813 boolean append)
814 throws IOException {
815
816 write(new File(pathName, fileName), s, lazy, append);
817 }
818
819 private static final String[] _SAFE_FILE_NAME_1 = {
820 StringPool.AMPERSAND, StringPool.CLOSE_PARENTHESIS,
821 StringPool.OPEN_PARENTHESIS, StringPool.SEMICOLON
822 };
823
824 private static final String[] _SAFE_FILE_NAME_2 = {
825 "_AMP_", "_CP_", "_OP_", "_SEM_"
826 };
827
828 private static Log _log = LogFactoryUtil.getLog(FileImpl.class);
829
830 private static FileImpl _instance = new FileImpl();
831
832 private static class ExtractTextProcessCallable
833 implements ProcessCallable<String> {
834
835 public ExtractTextProcessCallable(byte[] data) {
836 _data = data;
837 }
838
839 public String call() throws ProcessException {
840 Tika tika = new Tika();
841
842 try {
843 return tika.parseToString(
844 new UnsyncByteArrayInputStream(_data));
845 }
846 catch (Exception e) {
847 throw new ProcessException(e);
848 }
849 }
850
851 private byte[] _data;
852
853 }
854
855 }