001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
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    import java.util.concurrent.Future;
059    
060    import org.apache.commons.io.FileUtils;
061    import org.apache.commons.lang.exception.ExceptionUtils;
062    import org.apache.pdfbox.exceptions.CryptographyException;
063    import org.apache.poi.EncryptedDocumentException;
064    import org.apache.tika.Tika;
065    import org.apache.tools.ant.DirectoryScanner;
066    
067    import org.mozilla.intl.chardet.nsDetector;
068    import org.mozilla.intl.chardet.nsPSMDetector;
069    
070    /**
071     * @author Brian Wing Shun Chan
072     * @author Alexander Chow
073     */
074    public class FileImpl implements com.liferay.portal.kernel.util.File {
075    
076            public static FileImpl getInstance() {
077                    return _instance;
078            }
079    
080            public void copyDirectory(File source, File destination)
081                    throws IOException {
082    
083                    if (source.exists() && source.isDirectory()) {
084                            if (!destination.exists()) {
085                                    destination.mkdirs();
086                            }
087    
088                            File[] fileArray = source.listFiles();
089    
090                            for (int i = 0; i < fileArray.length; i++) {
091                                    if (fileArray[i].isDirectory()) {
092                                            copyDirectory(
093                                                    fileArray[i],
094                                                    new File(
095                                                            destination.getPath() + File.separator +
096                                                                    fileArray[i].getName()));
097                                    }
098                                    else {
099                                            copyFile(
100                                                    fileArray[i],
101                                                    new File(
102                                                            destination.getPath() + File.separator +
103                                                                    fileArray[i].getName()));
104                                    }
105                            }
106                    }
107            }
108    
109            public void copyDirectory(String sourceDirName, String destinationDirName)
110                    throws IOException {
111    
112                    copyDirectory(new File(sourceDirName), new File(destinationDirName));
113            }
114    
115            public void copyFile(File source, File destination) throws IOException {
116                    copyFile(source, destination, false);
117            }
118    
119            public void copyFile(File source, File destination, boolean lazy)
120                    throws IOException {
121    
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                            mkdirsParentFile(destination);
150    
151                            StreamUtil.transfer(
152                                    new FileInputStream(source), new FileOutputStream(destination));
153                    }
154            }
155    
156            public void copyFile(String source, String destination) throws IOException {
157                    copyFile(source, destination, false);
158            }
159    
160            public void copyFile(String source, String destination, boolean lazy)
161                    throws IOException {
162    
163                    copyFile(new File(source), new File(destination), lazy);
164            }
165    
166            public File createTempFile() {
167                    return createTempFile(StringPool.BLANK);
168            }
169    
170            public File createTempFile(byte[] bytes) throws IOException {
171                    File file = createTempFile(StringPool.BLANK);
172    
173                    write(file, bytes);
174    
175                    return file;
176            }
177    
178            public File createTempFile(InputStream is) throws IOException {
179                    File file = createTempFile(StringPool.BLANK);
180    
181                    write(file, is);
182    
183                    return file;
184            }
185    
186            public File createTempFile(String extension) {
187                    return new File(createTempFileName(extension));
188            }
189    
190            public String createTempFileName() {
191                    return createTempFileName(null);
192            }
193    
194            public String createTempFileName(String extension) {
195                    StringBundler sb = new StringBundler();
196    
197                    sb.append(SystemProperties.get(SystemProperties.TMP_DIR));
198                    sb.append(StringPool.SLASH);
199                    sb.append(Time.getTimestamp());
200                    sb.append(PwdGenerator.getPassword(PwdGenerator.KEY2, 8));
201    
202                    if (Validator.isFileExtension(extension)) {
203                            sb.append(StringPool.PERIOD);
204                            sb.append(extension);
205                    }
206    
207                    return sb.toString();
208            }
209    
210            public File createTempFolder() {
211                    File file = new File(createTempFileName());
212    
213                    file.mkdirs();
214    
215                    return file;
216            }
217    
218            public String decodeSafeFileName(String fileName) {
219                    return StringUtil.replace(
220                            fileName, _SAFE_FILE_NAME_2, _SAFE_FILE_NAME_1);
221            }
222    
223            public boolean delete(File file) {
224                    if (file != null) {
225                            boolean exists = true;
226    
227                            try {
228                                    exists = file.exists();
229                            }
230                            catch (SecurityException se) {
231    
232                                    // We may have the permission to delete a specific file without
233                                    // having the permission to check if the file exists
234    
235                            }
236    
237                            if (exists) {
238                                    return file.delete();
239                            }
240                    }
241    
242                    return false;
243            }
244    
245            public boolean delete(String file) {
246                    return delete(new File(file));
247            }
248    
249            public void deltree(File directory) {
250                    if (directory.exists() && directory.isDirectory()) {
251                            File[] fileArray = directory.listFiles();
252    
253                            for (int i = 0; i < fileArray.length; i++) {
254                                    if (fileArray[i].isDirectory()) {
255                                            deltree(fileArray[i]);
256                                    }
257                                    else {
258                                            fileArray[i].delete();
259                                    }
260                            }
261    
262                            directory.delete();
263                    }
264            }
265    
266            public void deltree(String directory) {
267                    deltree(new File(directory));
268            }
269    
270            public String encodeSafeFileName(String fileName) {
271                    if (fileName == null) {
272                            return StringPool.BLANK;
273                    }
274    
275                    return StringUtil.replace(
276                            fileName, _SAFE_FILE_NAME_1, _SAFE_FILE_NAME_2);
277            }
278    
279            public boolean exists(File file) {
280                    return file.exists();
281            }
282    
283            public boolean exists(String fileName) {
284                    return exists(new File(fileName));
285            }
286    
287            public String extractText(InputStream is, String fileName) {
288                    String text = null;
289    
290                    ClassLoader portalClassLoader = ClassLoaderUtil.getPortalClassLoader();
291    
292                    ClassLoader contextClassLoader =
293                            ClassLoaderUtil.getContextClassLoader();
294    
295                    try {
296                            if (contextClassLoader != portalClassLoader) {
297                                    ClassLoaderUtil.setContextClassLoader(portalClassLoader);
298                            }
299    
300                            Tika tika = new Tika();
301    
302                            tika.setMaxStringLength(-1);
303    
304                            boolean forkProcess = false;
305    
306                            if (PropsValues.TEXT_EXTRACTION_FORK_PROCESS_ENABLED) {
307                                    String mimeType = tika.detect(is);
308    
309                                    if (ArrayUtil.contains(
310                                                    PropsValues.TEXT_EXTRACTION_FORK_PROCESS_MIME_TYPES,
311                                                    mimeType)) {
312    
313                                            forkProcess = true;
314                                    }
315                            }
316    
317                            if (forkProcess) {
318                                    Future<String> future = ProcessExecutor.execute(
319                                            ClassPathUtil.getPortalClassPath(),
320                                            new ExtractTextProcessCallable(getBytes(is)));
321    
322                                    text = future.get();
323                            }
324                            else {
325                                    text = tika.parseToString(is);
326                            }
327                    }
328                    catch (Exception e) {
329                            Throwable throwable = ExceptionUtils.getRootCause(e);
330    
331                            if ((throwable instanceof CryptographyException) ||
332                                    (throwable instanceof EncryptedDocumentException)) {
333    
334                                    if (_log.isWarnEnabled()) {
335                                            _log.warn("Unable to extract text from an encrypted file");
336                                    }
337                            }
338                            else {
339                                    _log.error(e, e);
340                            }
341                    }
342                    finally {
343                            if (contextClassLoader != portalClassLoader) {
344                                    ClassLoaderUtil.setContextClassLoader(contextClassLoader);
345                            }
346                    }
347    
348                    if (_log.isInfoEnabled()) {
349                            if (text == null) {
350                                    _log.info("Text extraction failed for " + fileName);
351                            }
352                            else {
353                                    _log.info("Text was extracted for " + fileName);
354                            }
355                    }
356    
357                    if (_log.isDebugEnabled()) {
358                            _log.debug("Extractor returned text:\n\n" + text);
359                    }
360    
361                    if (text == null) {
362                            text = StringPool.BLANK;
363                    }
364    
365                    return text;
366            }
367    
368            public String[] find(String directory, String includes, String excludes) {
369                    if (directory.length() > 0) {
370                            directory = replaceSeparator(directory);
371    
372                            if (directory.charAt(directory.length() - 1) == CharPool.SLASH) {
373                                    directory = directory.substring(0, directory.length() - 1);
374                            }
375                    }
376    
377                    DirectoryScanner directoryScanner = new DirectoryScanner();
378    
379                    directoryScanner.setBasedir(directory);
380                    directoryScanner.setExcludes(StringUtil.split(excludes));
381                    directoryScanner.setIncludes(StringUtil.split(includes));
382    
383                    directoryScanner.scan();
384    
385                    String[] includedFiles = directoryScanner.getIncludedFiles();
386    
387                    for (int i = 0; i < includedFiles.length; i++) {
388                            includedFiles[i] = directory.concat(
389                                    StringPool.SLASH).concat(replaceSeparator(includedFiles[i]));
390                    }
391    
392                    return includedFiles;
393            }
394    
395            public String getAbsolutePath(File file) {
396                    return StringUtil.replace(
397                            file.getAbsolutePath(), CharPool.BACK_SLASH, CharPool.SLASH);
398            }
399    
400            public byte[] getBytes(File file) throws IOException {
401                    if ((file == null) || !file.exists()) {
402                            return null;
403                    }
404    
405                    RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
406    
407                    byte[] bytes = new byte[(int)randomAccessFile.length()];
408    
409                    randomAccessFile.readFully(bytes);
410    
411                    randomAccessFile.close();
412    
413                    return bytes;
414            }
415    
416            public byte[] getBytes(InputStream is) throws IOException {
417                    return getBytes(is, -1);
418            }
419    
420            public byte[] getBytes(InputStream inputStream, int bufferSize)
421                    throws IOException {
422    
423                    return getBytes(inputStream, bufferSize, true);
424            }
425    
426            public byte[] getBytes(
427                            InputStream inputStream, int bufferSize, boolean cleanUpStream)
428                    throws IOException {
429    
430                    if (inputStream == null) {
431                            return null;
432                    }
433    
434                    UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
435                            new UnsyncByteArrayOutputStream();
436    
437                    StreamUtil.transfer(
438                            inputStream, unsyncByteArrayOutputStream, bufferSize,
439                            cleanUpStream);
440    
441                    return unsyncByteArrayOutputStream.toByteArray();
442            }
443    
444            public String getExtension(String fileName) {
445                    if (fileName == null) {
446                            return null;
447                    }
448    
449                    int pos = fileName.lastIndexOf(CharPool.PERIOD);
450    
451                    if (pos > 0) {
452                            return fileName.substring(pos + 1, fileName.length()).toLowerCase();
453                    }
454                    else {
455                            return StringPool.BLANK;
456                    }
457            }
458    
459            public String getPath(String fullFileName) {
460                    int x = fullFileName.lastIndexOf(CharPool.SLASH);
461                    int y = fullFileName.lastIndexOf(CharPool.BACK_SLASH);
462    
463                    if ((x == -1) && (y == -1)) {
464                            return StringPool.SLASH;
465                    }
466    
467                    String shortFileName = fullFileName.substring(0, Math.max(x, y));
468    
469                    return shortFileName;
470            }
471    
472            public String getShortFileName(String fullFileName) {
473                    int x = fullFileName.lastIndexOf(CharPool.SLASH);
474                    int y = fullFileName.lastIndexOf(CharPool.BACK_SLASH);
475    
476                    String shortFileName = fullFileName.substring(Math.max(x, y) + 1);
477    
478                    return shortFileName;
479            }
480    
481            public boolean isAscii(File file) throws IOException {
482                    boolean ascii = true;
483    
484                    nsDetector detector = new nsDetector(nsPSMDetector.ALL);
485    
486                    InputStream inputStream = new FileInputStream(file);
487    
488                    byte[] buffer = new byte[1024];
489    
490                    int len = 0;
491    
492                    while ((len = inputStream.read(buffer, 0, buffer.length)) != -1) {
493                            if (ascii) {
494                                    ascii = detector.isAscii(buffer, len);
495    
496                                    if (!ascii) {
497                                            break;
498                                    }
499                            }
500                    }
501    
502                    detector.DataEnd();
503    
504                    inputStream.close();
505    
506                    return ascii;
507            }
508    
509            public boolean isSameContent(File file, byte[] bytes, int length) {
510                    FileChannel fileChannel = null;
511    
512                    try {
513                            FileInputStream fileInputStream = new FileInputStream(file);
514    
515                            fileChannel = fileInputStream.getChannel();
516    
517                            if (fileChannel.size() != length) {
518                                    return false;
519                            }
520    
521                            byte[] buffer = new byte[1024];
522    
523                            ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
524    
525                            int bufferIndex = 0;
526                            int bufferLength = -1;
527    
528                            while (((bufferLength = fileChannel.read(byteBuffer)) > 0) &&
529                                       (bufferIndex < length)) {
530    
531                                    for (int i = 0; i < bufferLength; i++) {
532                                            if (buffer[i] != bytes[bufferIndex++]) {
533                                                    return false;
534                                            }
535                                    }
536    
537                                    byteBuffer.clear();
538                            }
539    
540                            if ((bufferIndex != length) || (bufferLength != -1)) {
541                                    return false;
542                            }
543                            else {
544                                    return true;
545                            }
546                    }
547                    catch (Exception e) {
548                            return false;
549                    }
550                    finally {
551                            if (fileChannel != null) {
552                                    try {
553                                            fileChannel.close();
554                                    }
555                                    catch (IOException ioe) {
556                                    }
557                            }
558                    }
559            }
560    
561            public boolean isSameContent(File file, String s) {
562                    ByteBuffer byteBuffer = CharsetEncoderUtil.encode(StringPool.UTF8, s);
563    
564                    return isSameContent(file, byteBuffer.array(), byteBuffer.limit());
565            }
566    
567            public String[] listDirs(File file) {
568                    List<String> dirs = new ArrayList<String>();
569    
570                    File[] fileArray = file.listFiles();
571    
572                    for (int i = 0; (fileArray != null) && (i < fileArray.length); i++) {
573                            if (fileArray[i].isDirectory()) {
574                                    dirs.add(fileArray[i].getName());
575                            }
576                    }
577    
578                    return dirs.toArray(new String[dirs.size()]);
579            }
580    
581            public String[] listDirs(String fileName) {
582                    return listDirs(new File(fileName));
583            }
584    
585            public String[] listFiles(File file) {
586                    List<String> files = new ArrayList<String>();
587    
588                    File[] fileArray = file.listFiles();
589    
590                    for (int i = 0; (fileArray != null) && (i < fileArray.length); i++) {
591                            if (fileArray[i].isFile()) {
592                                    files.add(fileArray[i].getName());
593                            }
594                    }
595    
596                    return files.toArray(new String[files.size()]);
597            }
598    
599            public String[] listFiles(String fileName) {
600                    if (Validator.isNull(fileName)) {
601                            return new String[0];
602                    }
603    
604                    return listFiles(new File(fileName));
605            }
606    
607            public void mkdirs(String pathName) {
608                    File file = new File(pathName);
609    
610                    file.mkdirs();
611            }
612    
613            public boolean move(File source, File destination) {
614                    if (!source.exists()) {
615                            return false;
616                    }
617    
618                    destination.delete();
619    
620                    try {
621                            if (source.isDirectory()) {
622                                    FileUtils.moveDirectory(source, destination);
623                            }
624                            else {
625                                    FileUtils.moveFile(source, destination);
626                            }
627                    }
628                    catch (IOException ioe) {
629                            return false;
630                    }
631    
632                    return true;
633            }
634    
635            public boolean move(String sourceFileName, String destinationFileName) {
636                    return move(new File(sourceFileName), new File(destinationFileName));
637            }
638    
639            public String read(File file) throws IOException {
640                    return read(file, false);
641            }
642    
643            public String read(File file, boolean raw) throws IOException {
644                    byte[] bytes = getBytes(file);
645    
646                    if (bytes == null) {
647                            return null;
648                    }
649    
650                    String s = new String(bytes, StringPool.UTF8);
651    
652                    if (raw) {
653                            return s;
654                    }
655                    else {
656                            return StringUtil.replace(
657                                    s, StringPool.RETURN_NEW_LINE, StringPool.NEW_LINE);
658                    }
659            }
660    
661            public String read(String fileName) throws IOException {
662                    return read(new File(fileName));
663            }
664    
665            public String replaceSeparator(String fileName) {
666                    return StringUtil.replace(
667                            fileName, CharPool.BACK_SLASH, CharPool.SLASH);
668            }
669    
670            public File[] sortFiles(File[] files) {
671                    if (files == null) {
672                            return null;
673                    }
674    
675                    Arrays.sort(files, new FileComparator());
676    
677                    List<File> directoryList = new ArrayList<File>();
678                    List<File> fileList = new ArrayList<File>();
679    
680                    for (int i = 0; i < files.length; i++) {
681                            if (files[i].isDirectory()) {
682                                    directoryList.add(files[i]);
683                            }
684                            else {
685                                    fileList.add(files[i]);
686                            }
687                    }
688    
689                    directoryList.addAll(fileList);
690    
691                    return directoryList.toArray(new File[directoryList.size()]);
692            }
693    
694            public String stripExtension(String fileName) {
695                    if (fileName == null) {
696                            return null;
697                    }
698    
699                    String ext = getExtension(fileName);
700    
701                    if (ext.length() > 0) {
702                            return fileName.substring(0, fileName.length() - ext.length() - 1);
703                    }
704                    else {
705                            return fileName;
706                    }
707            }
708    
709            public List<String> toList(Reader reader) {
710                    List<String> list = new ArrayList<String>();
711    
712                    try {
713                            UnsyncBufferedReader unsyncBufferedReader =
714                                    new UnsyncBufferedReader(reader);
715    
716                            String line = null;
717    
718                            while ((line = unsyncBufferedReader.readLine()) != null) {
719                                    list.add(line);
720                            }
721    
722                            unsyncBufferedReader.close();
723                    }
724                    catch (IOException ioe) {
725                    }
726    
727                    return list;
728            }
729    
730            public List<String> toList(String fileName) {
731                    try {
732                            return toList(new FileReader(fileName));
733                    }
734                    catch (IOException ioe) {
735                            return new ArrayList<String>();
736                    }
737            }
738    
739            public Properties toProperties(FileInputStream fis) {
740                    Properties properties = new Properties();
741    
742                    try {
743                            properties.load(fis);
744                    }
745                    catch (IOException ioe) {
746                    }
747    
748                    return properties;
749            }
750    
751            public Properties toProperties(String fileName) {
752                    try {
753                            return toProperties(new FileInputStream(fileName));
754                    }
755                    catch (IOException ioe) {
756                            return new Properties();
757                    }
758            }
759    
760            public void touch(File file) throws IOException {
761                    FileUtils.touch(file);
762            }
763    
764            public void touch(String fileName) throws IOException {
765                    touch(new File(fileName));
766            }
767    
768            public void unzip(File source, File destination) {
769                    ExpandTask.expand(source, destination);
770            }
771    
772            public void write(File file, byte[] bytes) throws IOException {
773                    write(file, bytes, 0, bytes.length);
774            }
775    
776            public void write(File file, byte[] bytes, int offset, int length)
777                    throws IOException {
778    
779                    mkdirsParentFile(file);
780    
781                    FileOutputStream fileOutputStream = new FileOutputStream(file);
782    
783                    fileOutputStream.write(bytes, offset, length);
784    
785                    fileOutputStream.close();
786            }
787    
788            public void write(File file, InputStream is) throws IOException {
789                    mkdirsParentFile(file);
790    
791                    StreamUtil.transfer(is, new FileOutputStream(file));
792            }
793    
794            public void write(File file, String s) throws IOException {
795                    write(file, s, false);
796            }
797    
798            public void write(File file, String s, boolean lazy) throws IOException {
799                    write(file, s, lazy, false);
800            }
801    
802            public void write(File file, String s, boolean lazy, boolean append)
803                    throws IOException {
804    
805                    if (s == null) {
806                            return;
807                    }
808    
809                    mkdirsParentFile(file);
810    
811                    if (lazy && file.exists()) {
812                            String content = read(file);
813    
814                            if (content.equals(s)) {
815                                    return;
816                            }
817                    }
818    
819                    Writer writer = new OutputStreamWriter(
820                            new FileOutputStream(file, append), StringPool.UTF8);
821    
822                    writer.write(s);
823    
824                    writer.close();
825            }
826    
827            public void write(String fileName, byte[] bytes) throws IOException {
828                    write(new File(fileName), bytes);
829            }
830    
831            public void write(String fileName, InputStream is) throws IOException {
832                    write(new File(fileName), is);
833            }
834    
835            public void write(String fileName, String s) throws IOException {
836                    write(new File(fileName), s);
837            }
838    
839            public void write(String fileName, String s, boolean lazy)
840                    throws IOException {
841    
842                    write(new File(fileName), s, lazy);
843            }
844    
845            public void write(String fileName, String s, boolean lazy, boolean append)
846                    throws IOException {
847    
848                    write(new File(fileName), s, lazy, append);
849            }
850    
851            public void write(String pathName, String fileName, String s)
852                    throws IOException {
853    
854                    write(new File(pathName, fileName), s);
855            }
856    
857            public void write(String pathName, String fileName, String s, boolean lazy)
858                    throws IOException {
859    
860                    write(new File(pathName, fileName), s, lazy);
861            }
862    
863            public void write(
864                            String pathName, String fileName, String s, boolean lazy,
865                            boolean append)
866                    throws IOException {
867    
868                    write(new File(pathName, fileName), s, lazy, append);
869            }
870    
871            protected void mkdirsParentFile(File file) {
872                    File parentFile = file.getParentFile();
873    
874                    if (parentFile == null) {
875                            return;
876                    }
877    
878                    try {
879                            if (!parentFile.exists()) {
880                                    parentFile.mkdirs();
881                            }
882                    }
883                    catch (SecurityException se) {
884    
885                            // We may have the permission to write a specific file without
886                            // having the permission to check if the parent file exists
887    
888                    }
889            }
890    
891            private static final String[] _SAFE_FILE_NAME_1 = {
892                    StringPool.AMPERSAND, StringPool.CLOSE_PARENTHESIS,
893                    StringPool.OPEN_PARENTHESIS, StringPool.SEMICOLON
894            };
895    
896            private static final String[] _SAFE_FILE_NAME_2 = {
897                    "_AMP_", "_CP_", "_OP_", "_SEM_"
898            };
899    
900            private static Log _log = LogFactoryUtil.getLog(FileImpl.class);
901    
902            private static FileImpl _instance = new FileImpl();
903    
904            private static class ExtractTextProcessCallable
905                    implements ProcessCallable<String> {
906    
907                    public ExtractTextProcessCallable(byte[] data) {
908                            _data = data;
909                    }
910    
911                    public String call() throws ProcessException {
912                            Tika tika = new Tika();
913    
914                            try {
915                                    return tika.parseToString(
916                                            new UnsyncByteArrayInputStream(_data));
917                            }
918                            catch (Exception e) {
919                                    throw new ProcessException(e);
920                            }
921                    }
922    
923                    private static final long serialVersionUID = 1L;
924    
925                    private byte[] _data;
926    
927            }
928    
929    }