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

COVERAGE SUMMARY FOR SOURCE FILE [Jomic.java]

nameclass, %method, %block, %line, %
Jomic.java100% (2/2)75%  (9/12)68%  (281/411)68%  (71.6/105)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Jomic100% (1/1)70%  (7/10)68%  (268/395)67%  (64.6/96)
exitWithError (Throwable): void 0%   (0/1)0%   (0/33)0%   (0/13)
isReadyForOpen (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
setComicFile (File): void 0%   (0/1)0%   (0/4)0%   (0/2)
Jomic (File): void 100% (1/1)30%  (13/43)84%  (4.2/5)
<static initializer> 100% (1/1)68%  (17/25)70%  (1.4/2)
main (String []): void 100% (1/1)75%  (112/150)72%  (27.5/38)
setupImaging (Settings): void 100% (1/1)79%  (34/43)79%  (9.5/12)
show (): void 100% (1/1)92%  (22/24)89%  (8/9)
clearCache (): void 100% (1/1)100% (40/40)100% (11/11)
logEnvironment (): void 100% (1/1)100% (30/30)100% (3/3)
     
class Jomic$JomicRunner100% (1/1)100% (2/2)81%  (13/16)78%  (7/9)
run (): void 100% (1/1)70%  (7/10)67%  (4/6)
Jomic$JomicRunner (Jomic): void 100% (1/1)100% (6/6)100% (3/3)

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;
17 
18import java.io.File;
19import java.io.IOException;
20import java.io.PrintStream;
21import java.util.Iterator;
22 
23import javax.imageio.ImageIO;
24import javax.media.jai.JAI;
25import javax.media.jai.TileCache;
26import javax.swing.SwingUtilities;
27 
28import net.sf.jomic.comic.ComicCache;
29import net.sf.jomic.common.JomicJSAP;
30import net.sf.jomic.common.JomicStartup;
31import net.sf.jomic.common.PropertyConstants;
32import net.sf.jomic.common.Settings;
33import net.sf.jomic.common.SplashScreen;
34import net.sf.jomic.common.StartupTools;
35import net.sf.jomic.common.Version;
36import net.sf.jomic.tools.FileTools;
37import net.sf.jomic.tools.ItemMustBeDownloadedException;
38import net.sf.jomic.tools.LocaleTools;
39import net.sf.jomic.tools.StandardConstants;
40import net.sf.jomic.tools.StringTools;
41import net.sf.jomic.ui.AwtExceptionHandler;
42import net.sf.jomic.ui.JomicApplication;
43import net.sf.wraplog.Logger;
44 
45import com.martiansoftware.jsap.JSAPResult;
46 
47/**
48 *  Platform independent Jomic application to view comic book archives.
49 *
50 * @author    Thomas Aglassinger
51 */
52public class Jomic implements StandardConstants
53{
54    private static Logger logger = Logger.getLogger(Jomic.class);
55 
56    /**
57     *  The comic to open on startup; <code>null</code> means no comic.
58     */
59    private File comicFile;
60    private boolean readyForOpen;
61 
62    public Jomic(File newComicFile) {
63        assert JomicStartup.instance().isStartup() : JomicStartup.class.getName()
64                + ".startup() must be called before creating a instance of " + Jomic.class.getName();
65        comicFile = newComicFile;
66        logEnvironment();
67    }
68 
69    protected void setComicFile(File newComicFile) {
70        comicFile = newComicFile;
71    }
72 
73    private void setupImaging(Settings settings)
74        throws IOException {
75        assert settings != null;
76 
77        // Set image cache
78        ComicCache comicCache = ComicCache.instance();
79 
80        comicCache.setUp(settings.getCacheDir(), MEGA_BYTE * settings.getArchiveCacheSizeInMb());
81 
82        // Set tile cache size
83        long tileCacheSize = MEGA_BYTE * settings.getTileCacheSizeInMb();
84        TileCache cache = JAI.getDefaultInstance().getTileCache();
85 
86        cache.setMemoryCapacity(tileCacheSize);
87 
88        // Set cache directory for ImageIO
89        try {
90            File imageIoCacheDir = settings.getImageIOCache();
91 
92            ImageIO.setCacheDirectory(imageIoCacheDir);
93        } catch (IOException error) {
94            logger.warn("cannot set ImageIO cache directory; using internal default cache", error);
95        }
96    }
97 
98    /**
99     *  Is the JomiFrame ready to open archives, in other words: is the initialization finished?
100     */
101    protected boolean isReadyForOpen() {
102        return readyForOpen;
103    }
104 
105    /**
106     *  Run the Jomic application using the command line arguments specified in <code>arguments</code>
107     *  .
108     */
109    public static void main(final String[] arguments) {
110        JomicStartup startup = JomicStartup.instance();
111        StartupTools startupTools = StartupTools.instance();
112        SplashScreen splashScreen = startupTools.openSplashScreen();
113 
114        try {
115            startup.startup();
116 
117            JomicJSAP jsap = new JomicJSAP();
118            JSAPResult options = jsap.parse(arguments);
119 
120            if (!options.success()) {
121                // Throw exception for broken command line.
122                Iterator errorRider = options.getErrorMessageIterator();
123                String errorMessage;
124 
125                if (errorRider.hasNext()) {
126                    errorMessage = (String) errorRider.next();
127                } else {
128                    errorMessage = null;
129                }
130                throw new IllegalArgumentException(errorMessage);
131            }
132 
133            Settings settings = Settings.instance();
134 
135            if (options.getBoolean(JomicJSAP.ARG_CLEAR_CACHE)) {
136                clearCache();
137            } else if (options.getBoolean(JomicJSAP.ARG_HELP)) {
138                jsap.printHelp(System.err);
139            } else if (options.getBoolean(JomicJSAP.ARG_LICENSE)) {
140                jsap.printLicense(System.out);
141            } else if (options.getBoolean(JomicJSAP.ARG_VERSION)) {
142                jsap.printVersion(System.out);
143            } else {
144                String comicFileName = options.getString(JomicJSAP.ARG_FILE);
145                boolean continueWithLastFile =
146                        options.getBoolean((JomicJSAP.ARG_CONTINUE));
147                File comicFile = null;
148 
149                settings.read(settings.getSettingsFile());
150                if (comicFileName == null) {
151                    if (continueWithLastFile) {
152                        comicFile = settings.getMostRecentFile();
153                    }
154                } else {
155                    comicFile = new File(comicFileName);
156                }
157 
158                System.setProperty("sun.awt.exception.handler", AwtExceptionHandler.class.getName());
159                if (logger.isInfoEnabled()) {
160                    logger.info("comic archive passed from command line: \"" + comicFile + "\"");
161                }
162                SwingUtilities.invokeLater(new JomicRunner(new Jomic(comicFile)));
163            }
164        } catch (Throwable error) {
165            exitWithError(error);
166        } finally {
167            startupTools.disposeSplashScreen(splashScreen);
168        }
169    }
170 
171    /**
172     *  Open comic viewer.
173     */
174    public void show()
175        throws IOException {
176        Settings settings = Settings.instance();
177 
178        setupImaging(settings);
179 
180        // TODO: fix that size is always reset
181        // fixSizeAndLocation();
182        JomicApplication application = JomicApplication.instance();
183 
184        readyForOpen = true;
185        if (comicFile != null) {
186            application.openInNewWindow(comicFile);
187            comicFile = null;
188        } else {
189            application.openInNewWindow();
190        }
191    }
192 
193    /**
194     *  Show dialog for <code>error</code> and exit. If <code>error</code> is a <code>ItemMustBeDownloadedException</code>
195     *  , also offer to download the missing item.
196     *
197     * @see    ItemMustBeDownloadedException
198     */
199    protected static void exitWithError(Throwable error) {
200        logger.error("stopping application", error);
201        if (error instanceof ItemMustBeDownloadedException) {
202            ItemMustBeDownloadedException downloadError = (ItemMustBeDownloadedException) error;
203 
204            downloadError.show();
205            try {
206                // HACK: prevent browser process from being killed prematurely when Jomic exits
207                Thread.sleep(PropertyConstants.BROWSER_STARTUP_DELAY);
208            } catch (InterruptedException interruption) {
209                logger.warn("sleep interrupted", interruption);
210            }
211        } else {
212            String message = LocaleTools.instance().getMessage("errors.cannotLaunchJomic");
213 
214            JomicStartup.instance().showError(message, error);
215        }
216        JomicStartup.instance().exit(1);
217    }
218 
219    /**
220     *  Remove cache directory and all files stored in any of the caches.
221     */
222    static void clearCache()
223        throws IOException {
224        Settings settings = Settings.instance();
225 
226        File settingsFile = settings.getSettingsFile();
227 
228        settings.read(settingsFile);
229 
230        File cacheDir = settings.getCacheDir();
231        FileTools fileTools = FileTools.instance();
232        StringTools stringTools = StringTools.instance();
233        PrintStream errStream = System.err;
234 
235        errStream.println("Clearing cache directory: " + stringTools.sourced(cacheDir));
236        logger.info("Clearing cache directory: {}", stringTools.sourced(cacheDir));
237        fileTools.attemptToDeleteAll(cacheDir, logger);
238    }
239 
240    /**
241     *  Log information about the environment Jomic runs on. This comes in handy when users submit
242     *  logs with bug reports.
243     */
244    private void logEnvironment() {
245        if (logger.isInfoEnabled()) {
246            logger.info(
247                    "version: jomic = "
248                    + Version.VERSION_TAG
249                    + ", java = "
250                    + System.getProperty("java.version")
251                    + ", platform = "
252                    + System.getProperty("os.name")
253                    + "-"
254                    + System.getProperty("os.version")
255                    + "-"
256                    + System.getProperty("os.arch"));
257        }
258    }
259 
260    /**
261     *  Runnable to show Jomic while in event-dispatching thread.
262     *
263     * @author    Thomas Aglassinger
264     */
265    protected static final class JomicRunner implements Runnable
266    {
267        private Jomic jomic;
268 
269        protected JomicRunner(Jomic newJomic) {
270            jomic = newJomic;
271        }
272 
273        public void run() {
274            try {
275                JomicApplication.instance().setUpFramelessMenuBar();
276                jomic.show();
277            } catch (Throwable error) {
278                exitWithError(error);
279            }
280        }
281    }
282}

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