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

COVERAGE SUMMARY FOR SOURCE FILE [AbstractCreateComicTask.java]

nameclass, %method, %block, %line, %
AbstractCreateComicTask.java100% (1/1)90%  (9/10)73%  (271/370)80%  (55.7/70)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class AbstractCreateComicTask100% (1/1)90%  (9/10)73%  (271/370)80%  (55.7/70)
getSourceBaseDir (): File 0%   (0/1)0%   (0/3)0%   (0/1)
AbstractCreateComicTask (File, String [], Map, File, Conversion): void 100% (1/1)67%  (75/112)73%  (14.7/20)
start (): void 100% (1/1)70%  (133/189)76%  (24.2/32)
<static initializer> 100% (1/1)80%  (12/15)80%  (0.8/1)
AbstractCreateComicTask (): void 100% (1/1)100% (17/17)100% (6/6)
enableAddedAtLeastOneImage (): void 100% (1/1)100% (4/4)100% (2/2)
getConversion (): Conversion 100% (1/1)100% (3/3)100% (1/1)
getImageInfo (File): ImageInfo 100% (1/1)100% (21/21)100% (5/5)
getTargetComicFile (): File 100% (1/1)100% (3/3)100% (1/1)
hasAddedAtLeastOneImage (): boolean 100% (1/1)100% (3/3)100% (1/1)

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.comic;
17 
18import java.io.File;
19import java.util.HashMap;
20import java.util.Map;
21 
22import net.sf.jomic.tools.AbstractTask;
23import net.sf.jomic.tools.FileTools;
24import net.sf.jomic.tools.IOExceptionWithCause;
25import net.sf.jomic.tools.ImageInfo;
26import net.sf.jomic.tools.LocaleTools;
27import net.sf.jomic.tools.StringTools;
28import net.sf.wraplog.Logger;
29 
30/**
31 *  Task to create comic from a set of image files.
32 *
33 * @author    Thomas Aglassinger
34 */
35public abstract class AbstractCreateComicTask extends AbstractTask
36{
37    private Conversion conversion;
38    private FileTools fileTools;
39    private Map imageInfoMap;
40    private LocaleTools localeTools;
41    private Logger logger;
42    private File sourceBaseDir;
43    private String[] sourceFileNames;
44    private StringTools stringTools;
45    private File targetComicFile;
46    private boolean wroteAnyImages;
47 
48    /**
49     *  Create a new task to create a comic.
50     *
51     * @see                        ImageInfo
52     * @param  newSourceBaseDir    the base directory where the source files are located
53     * @param  newSourceFileNames  the names of the files relative to <code>newSourceBaseDir</code>
54     *      that should be included in the archive
55     * @param  newImageInfoMap     a map of <code>ImageInfos</code> used to decide if images can be
56     *      added. If this is <code>null</code>, the <code>ImageInfo</code> is filled during <code>start()</code>
57     *      .
58     * @param  newTargetComicFile  the comic file to create
59     * @param  newConversion       a conversion specifying the format and image manipulations of the
60     *      new comic; if null, the default will be a conversion creating a CBZ including all the
61     *      images specified.
62     */
63    public AbstractCreateComicTask(File newSourceBaseDir, String[] newSourceFileNames,
64            Map newImageInfoMap, File newTargetComicFile, Conversion newConversion) {
65        this();
66        assert newTargetComicFile != null;
67        assert newSourceBaseDir != null;
68        assert newSourceFileNames != null;
69        assert newSourceFileNames.length > 0;
70        assert newConversion != null;
71        sourceBaseDir = newSourceBaseDir;
72        sourceFileNames = newSourceFileNames;
73        if (newImageInfoMap == null) {
74            imageInfoMap = new HashMap();
75        } else {
76            imageInfoMap = newImageInfoMap;
77        }
78        targetComicFile = newTargetComicFile;
79        conversion = newConversion;
80        for (int i = 0; i < sourceFileNames.length; i += 1) {
81            File sourceFile = new File(sourceBaseDir, sourceFileNames[i]);
82 
83            if (!sourceFile.isFile()) {
84                String message = localeTools.getMessage(
85                        "errors.itemAddedToZipArchiveMustBeFile", stringTools.sourced(sourceFile));
86 
87                throw new IllegalArgumentException(message);
88            }
89            setMaxProgress(getMaxProgress() + 1 + sourceFile.length());
90        }
91    }
92 
93    private AbstractCreateComicTask() {
94        super();
95        logger = Logger.getLogger(this.getClass());
96        fileTools = FileTools.instance();
97        localeTools = LocaleTools.instance();
98        stringTools = StringTools.instance();
99    }
100 
101    /**
102     *  Allocate all resources needed to create the target comic file. They will be released when
103     *  done by calling <code>cleanUpComic()</code> either when done or an error occurs.
104     *
105     * @see    #cleanUpComic()
106     */
107    protected abstract void setUpComic()
108        throws Exception;
109 
110    protected final Conversion getConversion() {
111        return conversion;
112    }
113 
114    protected final File getSourceBaseDir() {
115        return sourceBaseDir;
116    }
117 
118    protected final File getTargetComicFile() {
119        return targetComicFile;
120    }
121 
122    /**
123     *  Obtain the <code>imageInfo</code> for <code>imageFile</code>, preferably from the <code>newImageInfoMap</code>
124     *  passed to the constructor. If the image can not be found in the map, obtain a new <code>ImageInfo</code>
125     *  for it and put it in the map for later reuse.
126     */
127    protected ImageInfo getImageInfo(File imageFile) {
128        ImageInfo result = (ImageInfo) imageInfoMap.get(imageFile);
129 
130        if (result == null) {
131            result = new ImageInfo(imageFile);
132            imageInfoMap.put(imageFile, result);
133        }
134        return result;
135    }
136 
137    public void start()
138        throws Exception {
139        boolean allFilesProcessed = false;
140 
141        if (logger.isInfoEnabled()) {
142            logger.info("create comic: " + targetComicFile);
143        }
144        String creatingMessage = localeTools.getMessage("progress.create.creating", targetComicFile.getName());
145 
146        setProgressMessage(creatingMessage);
147 
148        File targetFolder = targetComicFile.getParentFile();
149 
150        fileTools.mkdirs(targetFolder);
151        setUpComic();
152        try {
153            setProgress(0);
154            wroteAnyImages = false;
155            for (int i = 0; !isInterrupted() && (i < sourceFileNames.length); i += 1) {
156                String sourceName = sourceFileNames[i];
157                File sourceImageFile = new File(sourceBaseDir, sourceName);
158                ImageInfo imageInfo = getImageInfo(sourceImageFile);
159                String imageFormat = imageInfo.getFormat();
160                String outName = sourceFileNames[i];
161 
162                outName = fileTools.getWithoutLastSuffix(outName);
163                outName = outName + "." + conversion.getImageFormatName(imageFormat);
164                addImageFile(outName, sourceImageFile);
165            }
166            allFilesProcessed = !isInterrupted();
167        } finally {
168            Throwable cause = null;
169 
170            try {
171                cleanUpComic();
172            } catch (Throwable error) {
173                cause = error;
174            }
175            if (!allFilesProcessed || !wroteAnyImages) {
176                // Delete incomplete or empty archive.
177                fileTools.deleteOrWarn(targetComicFile, logger);
178            }
179            if (cause != null) {
180                String message = localeTools.getMessage("errors.cannotCreateArchive", targetComicFile);
181 
182                throw new IOExceptionWithCause(message, cause);
183            }
184        }
185    }
186 
187    /**
188     *  Add an image file to the target comic stream/document/file/whatever.
189     *
190     * @param  outImageName     the name under which the image should be stored (if applicable for
191     *      the output format)
192     * @param  sourceImageFile  the source image file to be added
193     */
194    protected abstract void addImageFile(String outImageName, File sourceImageFile)
195        throws Exception;
196 
197    /**
198     *  Release all resources need allocated by <code>setUpComic()</code> to create the target comic
199     *  stream/document/file/whatever. This will be called <b>in any case</b> even if something went
200     *  wrong during <code>setUpComic()</code> so this routine must be able to handle <code>null</code>
201     *  values without resulting in <code>NullPointerExceptions</code>.
202     *
203     * @see    #setUpComic()
204     */
205    protected abstract void cleanUpComic()
206        throws Exception;
207 
208    /**
209     *  Must be called by <code>addImageFile</code> when an image actually was added.
210     *
211     * @see    #addImageFile(String, File)
212     */
213    protected void enableAddedAtLeastOneImage() {
214        wroteAnyImages = true;
215    }
216 
217    protected boolean hasAddedAtLeastOneImage() {
218        return wroteAnyImages;
219    }
220}

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