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