EMMA Coverage Report (generated Sun Apr 20 22:38:01 CEST 2008)
[all classes][net.sf.jomic.tools]

COVERAGE SUMMARY FOR SOURCE FILE [FileArchive.java]

nameclass, %method, %block, %line, %
FileArchive.java67%  (2/3)96%  (23/24)80%  (1139/1430)86%  (237.4/277)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class FileArchive$UnrarProgressOutputListener100% (1/1)100% (3/3)64%  (109/170)78%  (21.1/27)
<static initializer> 100% (1/1)53%  (8/15)53%  (0.5/1)
FileArchive$UnrarProgressOutputListener (FileArchive, String [], ProgressFram... 100% (1/1)64%  (28/44)82%  (6.6/8)
lineWritten (Process, String, int): void 100% (1/1)66%  (73/111)78%  (14/18)
     
class FileArchive100% (1/1)95%  (20/21)82%  (1030/1260)87%  (216.3/250)
getBaseName (): String 0%   (0/1)0%   (0/3)0%   (0/1)
ifCanceledThrowException (ProgressFrame): void 100% (1/1)33%  (6/18)40%  (2/5)
isCanceled (ProgressFrame): boolean 100% (1/1)44%  (4/9)44%  (0.4/1)
extract (File, String [], ProgressFrame, long): void 100% (1/1)60%  (75/124)74%  (15.6/21)
list (): String [] 100% (1/1)65%  (36/55)80%  (8/10)
setUnrarCommand (String): void 100% (1/1)67%  (8/12)83%  (2.5/3)
listZip (): List 100% (1/1)71%  (37/52)82%  (12.4/15)
removeExtracted (File): void 100% (1/1)75%  (85/113)77%  (13.1/17)
extractZip (File, String [], ProgressFrame, long): void 100% (1/1)79%  (163/207)86%  (36.9/43)
<static initializer> 100% (1/1)80%  (12/15)80%  (0.8/1)
FileArchive (): void 100% (1/1)81%  (21/26)97%  (6.8/7)
listRar (): List 100% (1/1)86%  (50/58)73%  (6.6/9)
extractRar (File, String [], ProgressFrame, long): void 100% (1/1)88%  (94/107)88%  (18.5/21)
advanceProgress (ProgressFrame, long): void 100% (1/1)92%  (46/50)96%  (8.7/9)
extractPdf (File, String [], ProgressFrame, long): void 100% (1/1)93%  (105/113)97%  (27.1/28)
FileArchive (File): void 100% (1/1)93%  (57/61)96%  (9.6/10)
listPdf (): List 100% (1/1)95%  (97/102)98%  (25.4/26)
throwMeaningfulUnrarException (ConsoleIOException): void 100% (1/1)99%  (118/119)94%  (17/18)
extract (File, String []): void 100% (1/1)100% (7/7)100% (2/2)
getFileType (): String 100% (1/1)100% (3/3)100% (1/1)
getPdfDocument (): PDDocument 100% (1/1)100% (6/6)100% (2/2)
     
class FileArchive$10%   (0/1)100% (0/0)100% (0/0)100% (0/0)

1// Jomic - a viewer for comic book archives.
2// Copyright (C) 2004-2008 Thomas Aglassinger
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16package net.sf.jomic.tools;
17 
18import java.io.BufferedInputStream;
19import java.io.BufferedOutputStream;
20import java.io.File;
21import java.io.FileOutputStream;
22import java.io.IOException;
23import java.io.InputStream;
24import java.text.DecimalFormat;
25import java.util.ArrayList;
26import java.util.Arrays;
27import java.util.Enumeration;
28import java.util.HashMap;
29import java.util.Iterator;
30import java.util.LinkedList;
31import java.util.List;
32import java.util.Map;
33import java.util.zip.ZipException;
34 
35import net.sf.wraplog.Logger;
36 
37import org.apache.tools.zip.ZipEntry;
38import org.apache.tools.zip.ZipFile;
39import org.pdfbox.pdmodel.PDDocument;
40import org.pdfbox.pdmodel.PDPage;
41import org.pdfbox.pdmodel.PDResources;
42import org.pdfbox.pdmodel.graphics.xobject.PDXObjectImage;
43 
44/**
45 *  An archive containing files. Currently supported formats are ZIP and RAR.<p>
46 *
47 *  For hints and implementation details on various archive formats, see for example Marco Schmidt's
48 *  list of <a href="http://www.geocities.com/marcoschmidt.geo/archive-file-formats.html">archive
49 *  file formats and archivers</a> .
50 *
51 * @author    Thomas Aglassinger
52 */
53public class FileArchive
54{
55    private static final int BUFFER_SIZE = 4096;
56    // Unrar error codes.
57    private static final int UNRAR_ARCHIVE_MUST_BE_UNLOCKED = 4;
58    private static final int UNRAR_CANNOT_CREATE_FILE = 9;
59    private static final int UNRAR_CANNOT_OPEN_FILE = 6;
60    private static final int UNRAR_CANNOT_PROCESS_COMMAND_LINE_OPTION = 7;
61    private static final int UNRAR_CANNOT_WRITE = 5;
62    private static final int UNRAR_CHECKSUM_ERROR = 3;
63    private static final int UNRAR_FATAL_ERROR = 2;
64    private static final int UNRAR_INTERRUPTED = 255;
65    private static final int UNRAR_OUT_OF_MEMORY = 8;
66    private static final int UNRAR_WARNING = 1;
67 
68    private File archiveFile;
69    private String baseName;
70    private ConsoleTools consoleTools;
71    private FileTools fileTools;
72    private String fileType;
73    private LocaleTools localeTools;
74    private Logger logger;
75    private long progress;
76    private StringTools stringTools;
77 
78    /**
79     *  Command to run to list and extract RAR archives.
80     */
81    private String unrarCommand;
82 
83    public FileArchive(File newFile)
84        throws IOException {
85        this();
86        assert newFile != null;
87 
88        archiveFile = newFile;
89 
90        String suffix = fileTools.getSuffix(archiveFile);
91        String archiveName = archiveFile.getName();
92 
93        baseName = archiveName.substring(0, archiveName.length() - suffix.length() - 1);
94        if (logger.isDebugEnabled()) {
95            logger.debug("baseName = \"" + baseName + "\"");
96        }
97 
98        fileType = fileTools.obtainComicFormat(archiveFile);
99    }
100 
101    private FileArchive() {
102        super();
103        logger = Logger.getLogger(FileArchive.class);
104        consoleTools = ConsoleTools.instance();
105        fileTools = FileTools.instance();
106        localeTools = LocaleTools.instance();
107        stringTools = StringTools.instance();
108    }
109 
110    public void setUnrarCommand(String newUnrarCommand) {
111        assert newUnrarCommand != null;
112        unrarCommand = newUnrarCommand;
113    }
114 
115    /**
116     *  Get the plain name of the archive file, without directory and suffix. Example:
117     *  "/Users/me/Comics/blah.cbz" yields "blah".
118     */
119    public String getBaseName() {
120        return baseName;
121    }
122 
123    /**
124     *  Get the file type of the archive.
125     *
126     * @return    one of: FileTools.FORMAT_ZIP, FileTools.FORMAT_RAR, FileTools.FORMAT_PDF
127     */
128    public String getFileType() {
129        return fileType;
130    }
131 
132    private PDDocument getPdfDocument()
133        throws IOException {
134        PDDocument result = PDDocument.load(archiveFile);
135 
136        return result;
137    }
138 
139    private boolean isCanceled(ProgressFrame progressFrame) {
140        return (progressFrame != null) && (progressFrame.isCanceled());
141    }
142 
143    /**
144     *  Extract to <code>targetDir</code> all files in <code>fileNamesToExtract</code>. If <code>progressFrame</code>
145     *  is not null, advance its progress bar by <code>progressIncrement</code> for every file that
146     *  is extracted.
147     */
148    public void extract(
149            File targetDir,
150            String[] fileNamesToExtract,
151            ProgressFrame progressFrame,
152            long progressIncrement)
153        throws IOException, InterruptedException {
154        assert targetDir != null;
155        assert fileNamesToExtract != null;
156 
157        // TODO: Proportional progress bar depending on archive size in bytes.
158        if (progressFrame != null) {
159            String message = localeTools.getMessage("progress.extracting");
160 
161            progressFrame.setNote(message);
162        }
163        boolean extracted = false;
164 
165        try {
166            if (fileType.equals(FileTools.FORMAT_PDF)) {
167                extractPdf(targetDir, fileNamesToExtract, progressFrame, progressIncrement);
168            } else if (fileType.equals(FileTools.FORMAT_RAR)) {
169                extractRar(targetDir, fileNamesToExtract, progressFrame, progressIncrement);
170            } else if (fileType.equals(FileTools.FORMAT_ZIP)) {
171                extractZip(targetDir, fileNamesToExtract, progressFrame, progressIncrement);
172            } else {
173                assert false : "fileType = " + fileType;
174            }
175            extracted = true;
176        } finally {
177            if (!extracted) {
178                logger.warn("extracting failed; removing possibly existing files");
179                if (progressFrame != null) {
180                    String message = localeTools.getMessage("progress.cleaningUp");
181 
182                    progressFrame.setNote(message);
183                }
184                removeExtracted(targetDir);
185            }
186        }
187    }
188 
189    public void extract(File targetDir, String[] fileNamesToExtract)
190        throws IOException, InterruptedException {
191        extract(targetDir, fileNamesToExtract, null, -1);
192    }
193 
194    public String[] list()
195        throws IOException, InterruptedException {
196        String[] result;
197        List archiveContents;
198 
199        // TODO: ProgressFrame.setNote("Examining...");?
200        if (fileType.equals(FileTools.FORMAT_RAR)) {
201            archiveContents = listRar();
202        } else if (fileType.equals(FileTools.FORMAT_ZIP)) {
203            archiveContents = listZip();
204        } else if (fileType.equals(FileTools.FORMAT_PDF)) {
205            archiveContents = listPdf();
206        } else {
207            assert false : "fileType = " + fileType;
208            archiveContents = new ArrayList();
209        }
210        result = (String[]) archiveContents.toArray(new String[0]);
211        return result;
212    }
213 
214    /**
215     *  Attempt to remove all files that could have been extracted from the archive to <code>targetDir</code>
216     *  . If a file cannot be removed, log a warning and continue.
217     */
218    public void removeExtracted(File targetDir)
219        throws IOException, InterruptedException {
220        assert targetDir != null;
221        // TODO: Remove need to re-read the file list from the archive.
222        String[] files = list();
223 
224        for (int i = 0; i < files.length; i += 1) {
225            File file = new File(targetDir, files[i]);
226 
227            if (!file.delete()) {
228                logger.warn("cannot delete \"" + file + "\"");
229            } else {
230                if (logger.isDebugEnabled()) {
231                    logger.debug("deleted: \"" + file + "\"");
232                }
233            }
234 
235            File dir = file.getParentFile();
236 
237            while (!dir.equals(targetDir) && dir.delete()) {
238                if (logger.isDebugEnabled()) {
239                    logger.debug("deleted: \"" + dir + "\"");
240                }
241                dir = dir.getParentFile();
242            }
243        }
244        if (targetDir.delete()) {
245            if (logger.isDebugEnabled()) {
246                logger.debug("deleted: \"" + targetDir + "\"");
247            }
248        }
249    }
250 
251    private void advanceProgress(ProgressFrame progressFrame, long progressIncrement) {
252        assert (progressFrame == null) || (progressIncrement > 0);
253 
254        if (progressFrame != null) {
255            progress += progressIncrement;
256            if (logger.isDebugEnabled()) {
257                logger.debug("progress = " + progress);
258            }
259            progressFrame.setProgress(progress);
260        } else {
261            if (logger.isDebugEnabled()) {
262                logger.debug("no progress");
263            }
264        }
265    }
266 
267    private void extractPdf(
268            File targetDir,
269            String[] imageNames,
270            ProgressFrame progressFrame,
271            long progressIncrement)
272        throws IOException {
273        assert targetDir != null;
274        assert imageNames.length > 0;
275        PDDocument pdf = getPdfDocument();
276 
277        try {
278            List pages = pdf.getDocumentCatalog().getAllPages();
279            int imageIndex = 0;
280            Iterator iter = pages.iterator();
281 
282            progress = 0;
283            while (iter.hasNext()) {
284                PDPage page = (PDPage) iter.next();
285                PDResources resources = page.getResources();
286                Map images = resources.getImages();
287 
288                if (images != null) {
289                    Iterator imageIter = images.keySet().iterator();
290 
291                    while (imageIter.hasNext()) {
292                        String key = (String) imageIter.next();
293                        PDXObjectImage image = (PDXObjectImage) images.get(key);
294                        File imageFile = new File(targetDir, imageNames[imageIndex]);
295                        String name = imageFile.getAbsolutePath();
296 
297                        if (logger.isDebugEnabled()) {
298                            logger.debug("extracting image: " + StringTools.instance().sourced(name));
299                        }
300                        image.write2file(fileTools.getWithoutLastSuffix(name));
301                        advanceProgress(progressFrame, progressIncrement);
302                        imageIndex += 1;
303                    }
304                }
305            }
306        } finally {
307            pdf.close();
308        }
309    }
310 
311    //@ requires unrarCommand != null;
312    private void extractRar(
313            File targetDir,
314            String[] fileNamesToExtract,
315            ProgressFrame progressFrame,
316            long progressIncrement)
317        throws IOException, InterruptedException {
318        // Write names of files to extract to temporary file.
319        File filesToExtractListFile = File.createTempFile("jomic-unrar-list-", ".tmp");
320 
321        try {
322            fileTools.writeLines(filesToExtractListFile, fileNamesToExtract);
323 
324            UnrarProgressOutputListener progressListener =
325                    new UnrarProgressOutputListener(fileNamesToExtract, progressFrame, progressIncrement);
326            List arguments = new LinkedList();
327 
328            arguments.add(unrarCommand);
329            arguments.add("x");
330            arguments.add("-o+");
331            arguments.add("-y");
332            arguments.add("-c-");
333            arguments.add("-idp");
334            arguments.add("-n@" + filesToExtractListFile.getAbsolutePath());
335            arguments.add("--");
336            arguments.add(archiveFile.getAbsolutePath());
337            try {
338                consoleTools.run((String[]) arguments.toArray(new String[0]), targetDir, 0, progressListener);
339            } catch (ConsoleIOException error) {
340                throwMeaningfulUnrarException(error);
341            }
342 
343            ifCanceledThrowException(progressFrame);
344        } finally {
345            fileTools.attemptToDeleteAll(filesToExtractListFile, logger);
346        }
347    }
348 
349    private void extractZip(File targetDir, String[] imageNames, ProgressFrame progressFrame,
350            long progressIncrement)
351        throws IOException {
352        assert targetDir != null;
353        assert imageNames.length > 0;
354 
355        ZipFile zipFile = new ZipFile(archiveFile);
356 
357        try {
358            Enumeration zipEntries = zipFile.getEntries();
359            // Build a dictionary to quickly lookup image names for plain
360            // existance
361            String[] imageLookupMap = (String[]) imageNames.clone();
362 
363            Arrays.sort(imageLookupMap);
364 
365            progress = 0;
366            while (zipEntries.hasMoreElements()) {
367                ZipEntry entry = (ZipEntry) zipEntries.nextElement();
368                String name = entry.getName();
369 
370                if (!entry.isDirectory() && (Arrays.binarySearch(imageLookupMap, name) >= 0)) {
371                    advanceProgress(progressFrame, progressIncrement);
372 
373                    File targetFile = new File(targetDir, name);
374                    File targetParent = targetFile.getParentFile();
375 
376                    fileTools.mkdirs(targetParent);
377                    if (logger.isInfoEnabled()) {
378                        logger.info("extract \"" + name + "\" to \"" + targetFile.getAbsolutePath()
379                                + "\"");
380                    }
381                    InputStream in = zipFile.getInputStream(entry);
382 
383                    if (in == null) {
384                        // At least turn Sun bug 4244499 in a clear error
385                        // message.
386                        String message = localeTools.getMessage(
387                                "errors.nonAsciiCharactersMustBeRemoved", name);
388 
389                        throw new IOException(message);
390                    }
391                    try {
392                        BufferedInputStream inBuffered = new BufferedInputStream(in);
393 
394                        try {
395                            byte[] data = new byte[BUFFER_SIZE];
396                            FileOutputStream out = new FileOutputStream(targetFile);
397 
398                            try {
399                                BufferedOutputStream outBuffered = new BufferedOutputStream(out, BUFFER_SIZE);
400 
401                                try {
402                                    int bytesRead;
403 
404                                    while ((bytesRead = inBuffered.read(data, 0, BUFFER_SIZE)) != -1) {
405                                        ifCanceledThrowException(progressFrame);
406                                        outBuffered.write(data, 0, bytesRead);
407                                    }
408                                } finally {
409                                    outBuffered.close();
410                                }
411                            } finally {
412                                out.close();
413                            }
414                        } finally {
415                            inBuffered.close();
416                        }
417                    } finally {
418                        in.close();
419                    }
420                } else {
421                    if (logger.isDebugEnabled()) {
422                        logger.debug("ignore \"" + name + "\"");
423                    }
424                }
425            }
426        } finally {
427            zipFile.close();
428        }
429    }
430 
431    /**
432     *  Check if progressFrame has been canceld, and if so, throw a OperationCanceledException.
433     *
434     * @see    OperationCanceledException
435     */
436    private void ifCanceledThrowException(ProgressFrame progressFrame) {
437        if ((progressFrame != null) && (progressFrame.isCanceled())) {
438            if (logger.isDebugEnabled()) {
439                logger.debug("throwing OperationCanceledException");
440            }
441            throw new OperationCanceledException();
442        }
443    }
444 
445    private List listPdf()
446        throws IOException {
447        List result = new ArrayList();
448        PDDocument pdf = getPdfDocument();
449 
450        try {
451            List pages = pdf.getDocumentCatalog().getAllPages();
452            Iterator iter = pages.iterator();
453 
454            while (iter.hasNext()) {
455                PDPage page = (PDPage) iter.next();
456                PDResources resources = page.getResources();
457                Map images = resources.getImages();
458 
459                if (images != null) {
460                    Iterator imageIter = images.keySet().iterator();
461 
462                    while (imageIter.hasNext()) {
463                        String key = (String) imageIter.next();
464                        PDXObjectImage image = (PDXObjectImage) images.get(key);
465                        String suffix = image.getSuffix();
466 
467                        result.add(suffix);
468                    }
469                }
470            }
471 
472            // Assign numeric names to all images, but preserve the original suffix.
473            int imageCount = result.size();
474 
475            if (imageCount > 0) {
476                DecimalFormat format = stringTools.getLeadingZeroFormat(imageCount);
477 
478                for (int i = 0; i < imageCount; i += 1) {
479                    String name = format.format(i) + "." + result.get(i);
480 
481                    result.set(i, name);
482                }
483            }
484        } finally {
485            pdf.close();
486        }
487        return result;
488    }
489 
490    //@ ensures \result.size() > 0;
491    private List listRar()
492        throws IOException, InterruptedException {
493        assert unrarCommand != null;
494 
495        List result = null;
496        String[] arguments = new String[]{unrarCommand, "vb", "-y", "--", null};
497 
498        arguments[arguments.length - 1] = archiveFile.getAbsolutePath();
499        try {
500            result = consoleTools.run(arguments, null, 0);
501        } catch (ConsoleIOException error) {
502            throwMeaningfulUnrarException(error);
503        }
504        return result;
505    }
506 
507    private List listZip()
508        throws IOException {
509        List result = new ArrayList();
510        ZipFile zipFile = new ZipFile(archiveFile);
511        boolean foundAtLeastOneEntry = false;
512 
513        try {
514            Enumeration zipEntries = zipFile.getEntries();
515 
516            while (zipEntries.hasMoreElements()) {
517                foundAtLeastOneEntry = true;
518 
519                ZipEntry entry = (ZipEntry) zipEntries.nextElement();
520 
521                result.add(entry.getName());
522            }
523        } finally {
524            zipFile.close();
525        }
526        if (!foundAtLeastOneEntry) {
527            // This is the message java.util.ZipFile would cause in case the header is corrupted,
528            // although org.apache.tools.zip.ZipFile just returns no entries without any Exception.
529            String message = localeTools.getMessage("cannotParseZipHeaderJzentry0");
530 
531            throw new ZipException(message);
532        }
533 
534        return result;
535    }
536 
537    private void throwMeaningfulUnrarException(ConsoleIOException error)
538        throws IOException {
539        Map unrarExitCodeToErrorMap = new HashMap();
540 
541        unrarExitCodeToErrorMap.put(new Integer(UNRAR_WARNING), "warning");
542        unrarExitCodeToErrorMap.put(new Integer(UNRAR_FATAL_ERROR), "fatalError");
543        unrarExitCodeToErrorMap.put(new Integer(UNRAR_CHECKSUM_ERROR), "checksumError");
544        unrarExitCodeToErrorMap.put(new Integer(UNRAR_ARCHIVE_MUST_BE_UNLOCKED), "archiveMusteBeUnlocked");
545        unrarExitCodeToErrorMap.put(new Integer(UNRAR_CANNOT_WRITE), "cannotWrite");
546        unrarExitCodeToErrorMap.put(new Integer(UNRAR_CANNOT_OPEN_FILE), "cannotOpenFile");
547        unrarExitCodeToErrorMap.put(new Integer(UNRAR_CANNOT_PROCESS_COMMAND_LINE_OPTION), "cannotProcessCommandLineOptions");
548        unrarExitCodeToErrorMap.put(new Integer(UNRAR_OUT_OF_MEMORY), "outOfMemory");
549        unrarExitCodeToErrorMap.put(new Integer(UNRAR_CANNOT_CREATE_FILE), "cannotCreateFile");
550        unrarExitCodeToErrorMap.put(new Integer(UNRAR_INTERRUPTED), "interrupted");
551 
552        Integer exitCode = new Integer(error.getActualExitCode());
553        String errorId = (String) unrarExitCodeToErrorMap.get(exitCode);
554 
555        if (errorId != null) {
556            IOException meaningfulError = new IOException(localeTools.getMessage("errors.unrar." + errorId));
557 
558            meaningfulError.initCause(error);
559            throw meaningfulError;
560        }
561    }
562 
563    /**
564     *  Listener for unrar output to scan for expected filenames, and advance the progress bar.
565     */
566    private final class UnrarProgressOutputListener implements ConsoleOutputListener
567    {
568        private String[] fileNamesToExtract;
569        private ProgressFrame progressFrame;
570        private long progressIncrement;
571 
572        private UnrarProgressOutputListener(
573                String[] newFileNamesToExtract,
574                ProgressFrame newProgressFrame,
575                long newProgressIncrement) {
576            assert newFileNamesToExtract != null;
577            assert newFileNamesToExtract.length > 0;
578            assert (newProgressFrame == null) || (newProgressIncrement > 0);
579 
580            fileNamesToExtract = newFileNamesToExtract;
581            progressFrame = newProgressFrame;
582            progressIncrement = newProgressIncrement;
583        }
584 
585        /**
586         *  Called when unrar writes a line to the console during extracting. First, log the line.
587         *  Then check if it indicates that one of the images has been extracted. If so, advance the
588         *  progress bar.
589         */
590        public void lineWritten(Process process, String line, int streamType) {
591            assert process != null;
592            assert line != null;
593            if (streamType == STREAM_TYPE_ERR) {
594                logger.error("err: " + line);
595            } else if (streamType == STREAM_TYPE_OUT) {
596                if (logger.isDebugEnabled()) {
597                    logger.debug("out: " + line);
598                }
599                // check if the line indicates that one of the images was
600                // extracted
601                if (line.startsWith("Extracting")) {
602                    // TODO: use an exact and efficient algorithm
603                    // 1. we can discard extracted images from the list to lookup from
604                    // 2. check for exact matches of the name; in the worst case, name1 could be a substring of name2
605                    boolean containsExtractedImage = false;
606 
607                    for (int i = 0; !containsExtractedImage && (i < fileNamesToExtract.length); i += 1) {
608                        if (line.indexOf(fileNamesToExtract[i]) != -1) {
609                            containsExtractedImage = true;
610                        }
611                    }
612                    if (containsExtractedImage) {
613                        advanceProgress(progressFrame, progressIncrement);
614                    }
615                }
616                if (isCanceled(progressFrame)) {
617                    process.destroy();
618                }
619            } else {
620                assert false : "streamType = " + streamType;
621            }
622        }
623    }
624}

[all classes][net.sf.jomic.tools]
EMMA 2.0.4217 (C) Vladimir Roubtsov