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.ProcessChannel;
026 import com.liferay.portal.kernel.process.ProcessException;
027 import com.liferay.portal.kernel.process.ProcessExecutorUtil;
028 import com.liferay.portal.kernel.security.pacl.DoPrivileged;
029 import com.liferay.portal.kernel.util.ArrayUtil;
030 import com.liferay.portal.kernel.util.CharPool;
031 import com.liferay.portal.kernel.util.ClassLoaderUtil;
032 import com.liferay.portal.kernel.util.Digester;
033 import com.liferay.portal.kernel.util.DigesterUtil;
034 import com.liferay.portal.kernel.util.FileComparator;
035 import com.liferay.portal.kernel.util.PwdGenerator;
036 import com.liferay.portal.kernel.util.ReflectionUtil;
037 import com.liferay.portal.kernel.util.StreamUtil;
038 import com.liferay.portal.kernel.util.StringBundler;
039 import com.liferay.portal.kernel.util.StringPool;
040 import com.liferay.portal.kernel.util.StringUtil;
041 import com.liferay.portal.kernel.util.SystemProperties;
042 import com.liferay.portal.kernel.util.Time;
043 import com.liferay.portal.kernel.util.Validator;
044 import com.liferay.util.ant.ExpandTask;
045
046 import java.io.File;
047 import java.io.FileInputStream;
048 import java.io.FileOutputStream;
049 import java.io.FileReader;
050 import java.io.IOException;
051 import java.io.InputStream;
052 import java.io.OutputStreamWriter;
053 import java.io.RandomAccessFile;
054 import java.io.Reader;
055 import java.io.Writer;
056
057 import java.nio.ByteBuffer;
058 import java.nio.channels.FileChannel;
059
060 import java.util.ArrayList;
061 import java.util.Arrays;
062 import java.util.List;
063 import java.util.Properties;
064 import java.util.concurrent.Future;
065
066 import org.apache.commons.compress.archivers.zip.UnsupportedZipFeatureException;
067 import org.apache.commons.io.FileUtils;
068 import org.apache.commons.lang.exception.ExceptionUtils;
069 import org.apache.pdfbox.exceptions.CryptographyException;
070 import org.apache.poi.EncryptedDocumentException;
071 import org.apache.tika.Tika;
072 import org.apache.tika.exception.TikaException;
073 import org.apache.tools.ant.DirectoryScanner;
074
075 import org.mozilla.intl.chardet.nsDetector;
076 import org.mozilla.intl.chardet.nsPSMDetector;
077
078
082 @DoPrivileged
083 public class FileImpl implements com.liferay.portal.kernel.util.File {
084
085 public static FileImpl getInstance() {
086 return _instance;
087 }
088
089 @Override
090 public String appendParentheticalSuffix(String fileName, String suffix) {
091 String fileNameWithoutExtension = stripExtension(fileName);
092
093 String fileNameWithParentheticalSuffix =
094 StringUtil.appendParentheticalSuffix(
095 fileNameWithoutExtension, suffix);
096
097 String extension = getExtension(fileName);
098
099 if (Validator.isNull(extension)) {
100 return fileNameWithParentheticalSuffix;
101 }
102
103 StringBundler sb = new StringBundler(3);
104
105 sb.append(fileNameWithParentheticalSuffix);
106 sb.append(StringPool.PERIOD);
107 sb.append(extension);
108
109 return sb.toString();
110 }
111
112 @Override
113 public void copyDirectory(File source, File destination)
114 throws IOException {
115
116 if (!source.exists() || !source.isDirectory()) {
117 return;
118 }
119
120 mkdirs(destination);
121
122 File[] fileArray = source.listFiles();
123
124 for (int i = 0; i < fileArray.length; i++) {
125 if (fileArray[i].isDirectory()) {
126 copyDirectory(
127 fileArray[i],
128 new File(
129 destination.getPath() + File.separator +
130 fileArray[i].getName()));
131 }
132 else {
133 copyFile(
134 fileArray[i],
135 new File(
136 destination.getPath() + File.separator +
137 fileArray[i].getName()));
138 }
139 }
140 }
141
142 @Override
143 public void copyDirectory(String sourceDirName, String destinationDirName)
144 throws IOException {
145
146 copyDirectory(new File(sourceDirName), new File(destinationDirName));
147 }
148
149 @Override
150 public void copyFile(File source, File destination) throws IOException {
151 copyFile(source, destination, false);
152 }
153
154 @Override
155 public void copyFile(File source, File destination, boolean lazy)
156 throws IOException {
157
158 if (!source.exists()) {
159 return;
160 }
161
162 if (lazy) {
163 String oldContent = null;
164
165 try {
166 oldContent = read(source);
167 }
168 catch (Exception e) {
169 return;
170 }
171
172 String newContent = null;
173
174 try {
175 newContent = read(destination);
176 }
177 catch (Exception e) {
178 }
179
180 if ((oldContent == null) || !oldContent.equals(newContent)) {
181 copyFile(source, destination, false);
182 }
183 }
184 else {
185 mkdirsParentFile(destination);
186
187 StreamUtil.transfer(
188 new FileInputStream(source), new FileOutputStream(destination));
189 }
190 }
191
192 @Override
193 public void copyFile(String source, String destination) throws IOException {
194 copyFile(source, destination, false);
195 }
196
197 @Override
198 public void copyFile(String source, String destination, boolean lazy)
199 throws IOException {
200
201 copyFile(new File(source), new File(destination), lazy);
202 }
203
204 @Override
205 public File createTempFile() {
206 return createTempFile(StringPool.BLANK);
207 }
208
209 @Override
210 public File createTempFile(byte[] bytes) throws IOException {
211 File file = createTempFile(StringPool.BLANK);
212
213 write(file, bytes, false);
214
215 return file;
216 }
217
218 @Override
219 public File createTempFile(InputStream is) throws IOException {
220 File file = createTempFile(StringPool.BLANK);
221
222 write(file, is);
223
224 return file;
225 }
226
227 @Override
228 public File createTempFile(String extension) {
229 return new File(createTempFileName(extension));
230 }
231
232 @Override
233 public File createTempFile(String prefix, String extension) {
234 return new File(createTempFileName(prefix, extension));
235 }
236
237 @Override
238 public String createTempFileName() {
239 return createTempFileName(null, null);
240 }
241
242 @Override
243 public String createTempFileName(String extension) {
244 return createTempFileName(null, extension);
245 }
246
247 @Override
248 public String createTempFileName(String prefix, String extension) {
249 StringBundler sb = new StringBundler(7);
250
251 sb.append(SystemProperties.get(SystemProperties.TMP_DIR));
252 sb.append(StringPool.SLASH);
253
254 if (Validator.isNotNull(prefix)) {
255 sb.append(prefix);
256 }
257
258 sb.append(Time.getTimestamp());
259 sb.append(PwdGenerator.getPassword(8, PwdGenerator.KEY2));
260
261 if (Validator.isFileExtension(extension)) {
262 sb.append(StringPool.PERIOD);
263 sb.append(extension);
264 }
265
266 return sb.toString();
267 }
268
269 @Override
270 public File createTempFolder() throws IOException {
271 File file = new File(createTempFileName());
272
273 mkdirs(file);
274
275 return file;
276 }
277
278 @Override
279 public String decodeSafeFileName(String fileName) {
280 return StringUtil.replace(
281 fileName, _SAFE_FILE_NAME_2, _SAFE_FILE_NAME_1);
282 }
283
284 @Override
285 public boolean delete(File file) {
286 if (file != null) {
287 boolean exists = true;
288
289 try {
290 exists = file.exists();
291 }
292 catch (SecurityException se) {
293
294
295
296
297 }
298
299 if (exists) {
300 return file.delete();
301 }
302 }
303
304 return false;
305 }
306
307 @Override
308 public boolean delete(String file) {
309 return delete(new File(file));
310 }
311
312 @Override
313 public void deltree(File directory) {
314 if (directory.exists() && directory.isDirectory()) {
315 File[] fileArray = directory.listFiles();
316
317 for (int i = 0; i < fileArray.length; i++) {
318 if (fileArray[i].isDirectory()) {
319 deltree(fileArray[i]);
320 }
321 else {
322 fileArray[i].delete();
323 }
324 }
325
326 directory.delete();
327 }
328 }
329
330 @Override
331 public void deltree(String directory) {
332 deltree(new File(directory));
333 }
334
335 @Override
336 public String encodeSafeFileName(String fileName) {
337 if (fileName == null) {
338 return StringPool.BLANK;
339 }
340
341 return StringUtil.replace(
342 fileName, _SAFE_FILE_NAME_1, _SAFE_FILE_NAME_2);
343 }
344
345 @Override
346 public boolean exists(File file) {
347 return file.exists();
348 }
349
350 @Override
351 public boolean exists(String fileName) {
352 return exists(new File(fileName));
353 }
354
355 @Override
356 public String extractText(InputStream is, String fileName) {
357 return extractText(is, fileName, -1);
358 }
359
360 @Override
361 public String extractText(
362 InputStream is, String fileName, int maxStringLength) {
363
364 if (maxStringLength == 0) {
365 return StringPool.BLANK;
366 }
367
368 String text = null;
369
370 ClassLoader portalClassLoader = ClassLoaderUtil.getPortalClassLoader();
371
372 ClassLoader contextClassLoader =
373 ClassLoaderUtil.getContextClassLoader();
374
375 try {
376 if (contextClassLoader != portalClassLoader) {
377 ClassLoaderUtil.setContextClassLoader(portalClassLoader);
378 }
379
380 Tika tika = new Tika();
381
382 tika.setMaxStringLength(maxStringLength);
383
384 boolean forkProcess = false;
385
386 if (PropsValues.TEXT_EXTRACTION_FORK_PROCESS_ENABLED) {
387 String mimeType = tika.detect(is);
388
389 if (ArrayUtil.contains(
390 PropsValues.TEXT_EXTRACTION_FORK_PROCESS_MIME_TYPES,
391 mimeType)) {
392
393 forkProcess = true;
394 }
395 }
396
397 if (forkProcess) {
398 ProcessChannel<String> processChannel =
399 ProcessExecutorUtil.execute(
400 ClassPathUtil.getPortalProcessConfig(),
401 new ExtractTextProcessCallable(getBytes(is)));
402
403 Future<String> future =
404 processChannel.getProcessNoticeableFuture();
405
406 text = future.get();
407 }
408 else {
409 text = tika.parseToString(is);
410 }
411 }
412 catch (Exception e) {
413 Throwable throwable = ExceptionUtils.getRootCause(e);
414
415 if ((throwable instanceof CryptographyException) ||
416 (throwable instanceof EncryptedDocumentException) ||
417 (throwable instanceof UnsupportedZipFeatureException)) {
418
419 if (_log.isWarnEnabled()) {
420 _log.warn(
421 "Unable to extract text from an encrypted file " +
422 fileName);
423 }
424 }
425 else if (e instanceof TikaException) {
426 if (_log.isWarnEnabled()) {
427 _log.warn("Unable to extract text from " + fileName);
428 }
429 }
430 else {
431 _log.error(e, e);
432 }
433 }
434 finally {
435 if (contextClassLoader != portalClassLoader) {
436 ClassLoaderUtil.setContextClassLoader(contextClassLoader);
437 }
438 }
439
440 if (_log.isInfoEnabled()) {
441 if (text == null) {
442 _log.info("Text extraction failed for " + fileName);
443 }
444 else {
445 _log.info("Text was extracted for " + fileName);
446 }
447 }
448
449 if (_log.isDebugEnabled()) {
450 _log.debug("Extractor returned text:\n\n" + text);
451 }
452
453 if (text == null) {
454 text = StringPool.BLANK;
455 }
456
457 return text;
458 }
459
460 @Override
461 public String[] find(String directory, String includes, String excludes) {
462 if (directory.length() > 0) {
463 directory = replaceSeparator(directory);
464
465 if (directory.charAt(directory.length() - 1) == CharPool.SLASH) {
466 directory = directory.substring(0, directory.length() - 1);
467 }
468 }
469
470 if (!exists(directory)) {
471 if (_log.isWarnEnabled()) {
472 _log.warn("Directory " + directory + " does not exist");
473 }
474
475 return new String[0];
476 }
477
478 DirectoryScanner directoryScanner = new DirectoryScanner();
479
480 directoryScanner.setBasedir(directory);
481 directoryScanner.setExcludes(StringUtil.split(excludes));
482 directoryScanner.setIncludes(StringUtil.split(includes));
483
484 directoryScanner.scan();
485
486 String[] includedFiles = directoryScanner.getIncludedFiles();
487
488 for (int i = 0; i < includedFiles.length; i++) {
489 includedFiles[i] = directory.concat(
490 StringPool.SLASH).concat(replaceSeparator(includedFiles[i]));
491 }
492
493 return includedFiles;
494 }
495
496 @Override
497 public String getAbsolutePath(File file) {
498 return StringUtil.replace(
499 file.getAbsolutePath(), CharPool.BACK_SLASH, CharPool.SLASH);
500 }
501
502 @Override
503 public byte[] getBytes(Class<?> clazz, String fileName) throws IOException {
504 return getBytes(clazz.getResourceAsStream(fileName));
505 }
506
507 @Override
508 public byte[] getBytes(File file) throws IOException {
509 if ((file == null) || !file.exists()) {
510 return null;
511 }
512
513 try (RandomAccessFile randomAccessFile = new RandomAccessFile(
514 file, "r")) {
515
516 byte[] bytes = new byte[(int)randomAccessFile.length()];
517
518 randomAccessFile.readFully(bytes);
519
520 return bytes;
521 }
522 }
523
524 @Override
525 public byte[] getBytes(InputStream is) throws IOException {
526 return getBytes(is, -1);
527 }
528
529 @Override
530 public byte[] getBytes(InputStream inputStream, int bufferSize)
531 throws IOException {
532
533 return getBytes(inputStream, bufferSize, true);
534 }
535
536 @Override
537 public byte[] getBytes(
538 InputStream inputStream, int bufferSize, boolean cleanUpStream)
539 throws IOException {
540
541 if (inputStream == null) {
542 return null;
543 }
544
545 UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
546 new UnsyncByteArrayOutputStream();
547
548 StreamUtil.transfer(
549 inputStream, unsyncByteArrayOutputStream, bufferSize,
550 cleanUpStream);
551
552 return unsyncByteArrayOutputStream.toByteArray();
553 }
554
555 @Override
556 public String getExtension(String fileName) {
557 if (fileName == null) {
558 return null;
559 }
560
561 int pos = fileName.lastIndexOf(CharPool.PERIOD);
562
563 if (pos > 0) {
564 return StringUtil.toLowerCase(
565 fileName.substring(pos + 1, fileName.length()));
566 }
567 else {
568 return StringPool.BLANK;
569 }
570 }
571
572 @Override
573 public String getMD5Checksum(File file) throws IOException {
574 FileInputStream fileInputStream = null;
575
576 try {
577 fileInputStream = new FileInputStream(file);
578
579 return DigesterUtil.digestHex(Digester.MD5, fileInputStream);
580 }
581 finally {
582 StreamUtil.cleanUp(fileInputStream);
583 }
584 }
585
586 @Override
587 public String getPath(String fullFileName) {
588 int x = fullFileName.lastIndexOf(CharPool.SLASH);
589 int y = fullFileName.lastIndexOf(CharPool.BACK_SLASH);
590
591 if ((x == -1) && (y == -1)) {
592 return StringPool.SLASH;
593 }
594
595 String shortFileName = fullFileName.substring(0, Math.max(x, y));
596
597 return shortFileName;
598 }
599
600 @Override
601 public String getShortFileName(String fullFileName) {
602 int x = fullFileName.lastIndexOf(CharPool.SLASH);
603 int y = fullFileName.lastIndexOf(CharPool.BACK_SLASH);
604
605 String shortFileName = fullFileName.substring(Math.max(x, y) + 1);
606
607 return shortFileName;
608 }
609
610 @Override
611 public boolean isAscii(File file) throws IOException {
612 boolean ascii = true;
613
614 nsDetector detector = new nsDetector(nsPSMDetector.ALL);
615
616 try (InputStream inputStream = new FileInputStream(file)) {
617 byte[] buffer = new byte[1024];
618
619 int len = 0;
620
621 while ((len = inputStream.read(buffer, 0, buffer.length)) != -1) {
622 if (ascii) {
623 ascii = detector.isAscii(buffer, len);
624
625 if (!ascii) {
626 break;
627 }
628 }
629 }
630
631 detector.DataEnd();
632 }
633
634 return ascii;
635 }
636
637 @Override
638 public boolean isSameContent(File file, byte[] bytes, int length) {
639 FileChannel fileChannel = null;
640
641 try {
642 FileInputStream fileInputStream = new FileInputStream(file);
643
644 fileChannel = fileInputStream.getChannel();
645
646 if (fileChannel.size() != length) {
647 return false;
648 }
649
650 byte[] buffer = new byte[1024];
651
652 ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
653
654 int bufferIndex = 0;
655 int bufferLength = -1;
656
657 while (((bufferLength = fileChannel.read(byteBuffer)) > 0) &&
658 (bufferIndex < length)) {
659
660 for (int i = 0; i < bufferLength; i++) {
661 if (buffer[i] != bytes[bufferIndex++]) {
662 return false;
663 }
664 }
665
666 byteBuffer.clear();
667 }
668
669 if ((bufferIndex != length) || (bufferLength != -1)) {
670 return false;
671 }
672 else {
673 return true;
674 }
675 }
676 catch (Exception e) {
677 return false;
678 }
679 finally {
680 if (fileChannel != null) {
681 try {
682 fileChannel.close();
683 }
684 catch (IOException ioe) {
685 }
686 }
687 }
688 }
689
690 @Override
691 public boolean isSameContent(File file, String s) {
692 ByteBuffer byteBuffer = CharsetEncoderUtil.encode(StringPool.UTF8, s);
693
694 return isSameContent(file, byteBuffer.array(), byteBuffer.limit());
695 }
696
697 @Override
698 public String[] listDirs(File file) {
699 List<String> dirs = new ArrayList<>();
700
701 File[] fileArray = file.listFiles();
702
703 for (int i = 0; (fileArray != null) && (i < fileArray.length); i++) {
704 if (fileArray[i].isDirectory()) {
705 dirs.add(fileArray[i].getName());
706 }
707 }
708
709 return dirs.toArray(new String[dirs.size()]);
710 }
711
712 @Override
713 public String[] listDirs(String fileName) {
714 return listDirs(new File(fileName));
715 }
716
717 @Override
718 public String[] listFiles(File file) {
719 List<String> files = new ArrayList<>();
720
721 File[] fileArray = file.listFiles();
722
723 for (int i = 0; (fileArray != null) && (i < fileArray.length); i++) {
724 if (fileArray[i].isFile()) {
725 files.add(fileArray[i].getName());
726 }
727 }
728
729 return files.toArray(new String[files.size()]);
730 }
731
732 @Override
733 public String[] listFiles(String fileName) {
734 if (Validator.isNull(fileName)) {
735 return new String[0];
736 }
737
738 return listFiles(new File(fileName));
739 }
740
741 @Override
742 public void mkdirs(File file) throws IOException {
743 FileUtils.forceMkdir(file);
744 }
745
746 @Override
747 public void mkdirs(String pathName) {
748 File file = new File(pathName);
749
750 if (file.exists() && file.isDirectory()) {
751 if (_log.isDebugEnabled()) {
752 _log.debug("Directory " + pathName + " already exists");
753 }
754
755 return;
756 }
757
758 try {
759 mkdirs(file);
760 }
761 catch (IOException ioe) {
762 ReflectionUtil.throwException(ioe);
763 }
764 }
765
766 @Override
767 public boolean move(File source, File destination) {
768 if (!source.exists()) {
769 return false;
770 }
771
772 destination.delete();
773
774 try {
775 if (source.isDirectory()) {
776 FileUtils.moveDirectory(source, destination);
777 }
778 else {
779 FileUtils.moveFile(source, destination);
780 }
781 }
782 catch (IOException ioe) {
783 return false;
784 }
785
786 return true;
787 }
788
789 @Override
790 public boolean move(String sourceFileName, String destinationFileName) {
791 return move(new File(sourceFileName), new File(destinationFileName));
792 }
793
794 @Override
795 public String read(File file) throws IOException {
796 return read(file, false);
797 }
798
799 @Override
800 public String read(File file, boolean raw) throws IOException {
801 byte[] bytes = getBytes(file);
802
803 if (bytes == null) {
804 return null;
805 }
806
807 String s = new String(bytes, StringPool.UTF8);
808
809 if (raw) {
810 return s;
811 }
812 else {
813 return StringUtil.replace(
814 s, StringPool.RETURN_NEW_LINE, StringPool.NEW_LINE);
815 }
816 }
817
818 @Override
819 public String read(String fileName) throws IOException {
820 return read(new File(fileName));
821 }
822
823 @Override
824 public String replaceSeparator(String fileName) {
825 return StringUtil.replace(
826 fileName, CharPool.BACK_SLASH, CharPool.SLASH);
827 }
828
829 @Override
830 public File[] sortFiles(File[] files) {
831 if (files == null) {
832 return null;
833 }
834
835 Arrays.sort(files, new FileComparator());
836
837 List<File> directoryList = new ArrayList<>();
838 List<File> fileList = new ArrayList<>();
839
840 for (int i = 0; i < files.length; i++) {
841 if (files[i].isDirectory()) {
842 directoryList.add(files[i]);
843 }
844 else {
845 fileList.add(files[i]);
846 }
847 }
848
849 directoryList.addAll(fileList);
850
851 return directoryList.toArray(new File[directoryList.size()]);
852 }
853
854 @Override
855 public String stripExtension(String fileName) {
856 if (fileName == null) {
857 return null;
858 }
859
860 String ext = getExtension(fileName);
861
862 if (ext.length() > 0) {
863 return fileName.substring(0, fileName.length() - ext.length() - 1);
864 }
865 else {
866 return fileName;
867 }
868 }
869
870 @Override
871 public String stripParentheticalSuffix(String fileName) {
872 StringBundler sb = new StringBundler(3);
873
874 String fileNameWithoutExtension = stripExtension(fileName);
875
876 sb.append(
877 StringUtil.stripParentheticalSuffix(fileNameWithoutExtension));
878
879 sb.append(StringPool.PERIOD);
880
881 String extension = getExtension(fileName);
882
883 sb.append(extension);
884
885 return sb.toString();
886 }
887
888 @Override
889 public List<String> toList(Reader reader) {
890 List<String> list = new ArrayList<>();
891
892 try (UnsyncBufferedReader unsyncBufferedReader =
893 new UnsyncBufferedReader(reader)) {
894
895 String line = null;
896
897 while ((line = unsyncBufferedReader.readLine()) != null) {
898 list.add(line);
899 }
900 }
901 catch (IOException ioe) {
902 }
903
904 return list;
905 }
906
907 @Override
908 public List<String> toList(String fileName) {
909 try {
910 return toList(new FileReader(fileName));
911 }
912 catch (IOException ioe) {
913 return new ArrayList<>();
914 }
915 }
916
917 @Override
918 public Properties toProperties(FileInputStream fis) {
919 Properties properties = new Properties();
920
921 try {
922 properties.load(fis);
923 }
924 catch (IOException ioe) {
925 }
926
927 return properties;
928 }
929
930 @Override
931 public Properties toProperties(String fileName) {
932 try {
933 return toProperties(new FileInputStream(fileName));
934 }
935 catch (IOException ioe) {
936 return new Properties();
937 }
938 }
939
940 @Override
941 public void touch(File file) throws IOException {
942 FileUtils.touch(file);
943 }
944
945 @Override
946 public void touch(String fileName) throws IOException {
947 touch(new File(fileName));
948 }
949
950 @Override
951 public void unzip(File source, File destination) {
952 ExpandTask.expand(source, destination);
953 }
954
955 @Override
956 public void write(File file, byte[] bytes) throws IOException {
957 write(file, bytes, 0, bytes.length, false);
958 }
959
960 @Override
961 public void write(File file, byte[] bytes, boolean append)
962 throws IOException {
963
964 write(file, bytes, 0, bytes.length, append);
965 }
966
967 @Override
968 public void write(File file, byte[] bytes, int offset, int length)
969 throws IOException {
970
971 write(file, bytes, offset, bytes.length, false);
972 }
973
974 @Override
975 public void write(
976 File file, byte[] bytes, int offset, int length, boolean append)
977 throws IOException {
978
979 mkdirsParentFile(file);
980
981 try (FileOutputStream fileOutputStream = new FileOutputStream(
982 file, append)) {
983
984 fileOutputStream.write(bytes, offset, length);
985 }
986 }
987
988 @Override
989 public void write(File file, InputStream is) throws IOException {
990 mkdirsParentFile(file);
991
992 StreamUtil.transfer(is, new FileOutputStream(file));
993 }
994
995 @Override
996 public void write(File file, String s) throws IOException {
997 write(file, s, false);
998 }
999
1000 @Override
1001 public void write(File file, String s, boolean lazy) throws IOException {
1002 write(file, s, lazy, false);
1003 }
1004
1005 @Override
1006 public void write(File file, String s, boolean lazy, boolean append)
1007 throws IOException {
1008
1009 if (s == null) {
1010 return;
1011 }
1012
1013 mkdirsParentFile(file);
1014
1015 if (lazy && file.exists()) {
1016 String content = read(file);
1017
1018 if (content.equals(s)) {
1019 return;
1020 }
1021 }
1022
1023 try (Writer writer = new OutputStreamWriter(
1024 new FileOutputStream(file, append), StringPool.UTF8)) {
1025
1026 writer.write(s);
1027 }
1028 }
1029
1030 @Override
1031 public void write(String fileName, byte[] bytes) throws IOException {
1032 write(new File(fileName), bytes);
1033 }
1034
1035 @Override
1036 public void write(String fileName, InputStream is) throws IOException {
1037 write(new File(fileName), is);
1038 }
1039
1040 @Override
1041 public void write(String fileName, String s) throws IOException {
1042 write(new File(fileName), s);
1043 }
1044
1045 @Override
1046 public void write(String fileName, String s, boolean lazy)
1047 throws IOException {
1048
1049 write(new File(fileName), s, lazy);
1050 }
1051
1052 @Override
1053 public void write(String fileName, String s, boolean lazy, boolean append)
1054 throws IOException {
1055
1056 write(new File(fileName), s, lazy, append);
1057 }
1058
1059 @Override
1060 public void write(String pathName, String fileName, String s)
1061 throws IOException {
1062
1063 write(new File(pathName, fileName), s);
1064 }
1065
1066 @Override
1067 public void write(String pathName, String fileName, String s, boolean lazy)
1068 throws IOException {
1069
1070 write(new File(pathName, fileName), s, lazy);
1071 }
1072
1073 @Override
1074 public void write(
1075 String pathName, String fileName, String s, boolean lazy,
1076 boolean append)
1077 throws IOException {
1078
1079 write(new File(pathName, fileName), s, lazy, append);
1080 }
1081
1082 protected void mkdirsParentFile(File file) throws IOException {
1083 File parentFile = file.getParentFile();
1084
1085 if (parentFile == null) {
1086 return;
1087 }
1088
1089 try {
1090 mkdirs(parentFile);
1091 }
1092 catch (SecurityException se) {
1093
1094
1095
1096
1097 }
1098 }
1099
1100 private static final String[] _SAFE_FILE_NAME_1 = {
1101 StringPool.AMPERSAND, StringPool.CLOSE_PARENTHESIS,
1102 StringPool.OPEN_PARENTHESIS, StringPool.SEMICOLON
1103 };
1104
1105 private static final String[] _SAFE_FILE_NAME_2 = {
1106 "_AMP_", "_CP_", "_OP_", "_SEM_"
1107 };
1108
1109 private static final Log _log = LogFactoryUtil.getLog(FileImpl.class);
1110
1111 private static final FileImpl _instance = new FileImpl();
1112
1113 private static class ExtractTextProcessCallable
1114 implements ProcessCallable<String> {
1115
1116 public ExtractTextProcessCallable(byte[] data) {
1117 _data = data;
1118 }
1119
1120 @Override
1121 public String call() throws ProcessException {
1122 Tika tika = new Tika();
1123
1124 try {
1125 return tika.parseToString(
1126 new UnsyncByteArrayInputStream(_data));
1127 }
1128 catch (Exception e) {
1129 throw new ProcessException(e);
1130 }
1131 }
1132
1133 private static final long serialVersionUID = 1L;
1134
1135 private final byte[] _data;
1136
1137 }
1138
1139 }