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

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