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

COVERAGE SUMMARY FOR SOURCE FILE [JomicMacOSX.java]

nameclass, %method, %block, %line, %
JomicMacOSX.java0%   (0/1)0%   (0/10)0%   (0/359)0%   (0/87)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class JomicMacOSX0%   (0/1)0%   (0/10)0%   (0/359)0%   (0/87)
<static initializer> 0%   (0/1)0%   (0/15)0%   (0/1)
JomicMacOSX (): void 0%   (0/1)0%   (0/19)0%   (0/7)
actionPerformed (ActionEvent): void 0%   (0/1)0%   (0/81)0%   (0/17)
getJomic (): Jomic 0%   (0/1)0%   (0/3)0%   (0/1)
handleOpenFile (File): void 0%   (0/1)0%   (0/22)0%   (0/7)
main (String []): void 0%   (0/1)0%   (0/102)0%   (0/23)
setFileToBeOpened (File): void 0%   (0/1)0%   (0/60)0%   (0/13)
setInitialisationFinished (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setJomic (Jomic): void 0%   (0/1)0%   (0/12)0%   (0/3)
waitForInitialisationFinished (): void 0%   (0/1)0%   (0/41)0%   (0/13)

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.awt.event.ActionEvent;
19import java.io.File;
20import java.io.PrintStream;
21 
22import javax.swing.SwingUtilities;
23 
24import net.roydesign.event.ApplicationEvent;
25import net.sf.jomic.comic.ComicFileFilter;
26import net.sf.jomic.common.JomicStartup;
27import net.sf.jomic.common.Settings;
28import net.sf.jomic.common.SplashScreen;
29import net.sf.jomic.common.StartupTools;
30import net.sf.jomic.tools.LocaleTools;
31import net.sf.jomic.tools.StandardConstants;
32import net.sf.jomic.ui.JomicApplication;
33import net.sf.wraplog.Logger;
34 
35import com.apple.mrj.MRJApplicationUtils;
36import com.apple.mrj.MRJOpenDocumentHandler;
37 
38/**
39 *  Jomic application listening to Mac OS X application events, for example drag and drop in Finder.
40 *
41 * @author    Thomas Aglassinger
42 * @see       Jomic
43 */
44public final class JomicMacOSX implements MRJOpenDocumentHandler, StandardConstants
45{
46    private static final int INITIALIZATION_TIMEOUT = 30000;
47    private static final int WAITING_FOR_INITIALITATION_LOG_INTERVAL = 1000;
48    private static Logger logger;
49    private boolean initailisationFinished;
50    private Jomic jomic;
51    private JomicStartup startup;
52    private StartupTools startupTools;
53 
54    private JomicMacOSX() {
55        startupTools = StartupTools.instance();
56        startupTools.logDuration("entering JomicMacOSX()");
57 
58        // Start listening to Mac OS X application events. We have to do this
59        // as early as possible in order to prevent the event from getting
60        // lost. Otherwise, we could just let JomicApplication let listen for
61        // the "open document" event.
62        // TODO: Find non-deprecated way to handle "OpenDocument" events.
63        MRJApplicationUtils.registerOpenDocumentHandler(this);
64        startupTools.logDuration("after registerOpenDocumentHandler()");
65        startup = JomicStartup.instance();
66    }
67 
68    private void setFileToBeOpened(File file) {
69        if (file != null) {
70            ComicFileFilter comicFileFilter = new ComicFileFilter();
71 
72            if (comicFileFilter.accept(file, file.getName())) {
73                if (jomic.isReadyForOpen()) {
74                    JomicApplication.instance().openInNewWindow(file);
75                } else {
76                    if (logger.isInfoEnabled()) {
77                        logger.info("scheduling file to be opened when ready: \"" + file + "\"");
78                    }
79                    // TODO: support multiple files
80                    jomic.setComicFile(file);
81                }
82            } else {
83                logger.warn("rejecting file \"" + file + "\"");
84            }
85        } else {
86            if (logger.isDebugEnabled()) {
87                logger.debug("application event without file");
88            }
89        }
90    }
91 
92    private void setInitialisationFinished(boolean value) {
93        initailisationFinished = value;
94    }
95 
96    private void setJomic(Jomic newJomic) {
97        assert newJomic != null;
98        jomic = newJomic;
99    }
100 
101    private Jomic getJomic() {
102        return jomic;
103    }
104 
105    /**
106     *  Launch Jomic under Mac OS X, ignoring <code>arguments</code>.
107     */
108    public static void main(final String[] arguments) {
109        StartupTools startupTools = StartupTools.instance();
110 
111        startupTools.logDuration("entering main");
112 
113        JomicMacOSX launcher = new JomicMacOSX();
114 
115        startupTools.logDuration("application initialised");
116 
117        SplashScreen splashScreen = startupTools.openSplashScreen();
118 
119        startupTools.logDuration("SplashScreen opened");
120        try {
121            if (arguments.length > 0) {
122                throw new IllegalArgumentException("to pass command line arguments, "
123                        + Jomic.class.getName() + " must be used");
124            }
125            logger = Logger.getLogger(JomicMacOSX.class);
126 
127            JomicStartup startup = JomicStartup.instance();
128 
129            startup.startup();
130 
131            Settings settings = Settings.instance();
132 
133            settings.read(settings.getSettingsFile());
134            launcher.setJomic(new Jomic(null));
135            launcher.setInitialisationFinished(true);
136            startupTools.logDuration("Jomic initialised");
137            SwingUtilities.invokeLater(new Jomic.JomicRunner(launcher.getJomic()));
138            startupTools.logDuration("JomicRunner invoked");
139        } catch (Throwable error) {
140            Jomic.exitWithError(error);
141        } finally {
142            startupTools.disposeSplashScreen(splashScreen);
143        }
144    }
145 
146    /**
147     *  Handle Mac OS X application events. On other platforms, this method will never be called.
148     *
149     * @see    java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
150     */
151    public void actionPerformed(ActionEvent event) {
152        assert event instanceof ApplicationEvent : "event.class = " + event.getClass();
153 
154        waitForInitialisationFinished();
155 
156        ApplicationEvent appEvent = (ApplicationEvent) event;
157        // HACK: Silly name to prevent hiding the "startup" field inherited
158        // from net.sf.jomic.Jomic.
159        JomicStartup osxStartup = JomicStartup.instance();
160 
161        if (logger.isInfoEnabled()) {
162            logger.info("handle application event: " + appEvent);
163        }
164        try {
165            int type = appEvent.getType();
166 
167            if ((type == ApplicationEvent.OPEN_DOCUMENT) || (type == ApplicationEvent.REOPEN_APPLICATION)) {
168                File file = appEvent.getFile();
169 
170                setFileToBeOpened(file);
171            } else {
172                logger.warn("unknown application event: " + appEvent);
173            }
174        } catch (Throwable error) {
175            String message = LocaleTools.instance().getMessage(
176                    "errors.cannotProcessApplicationEvent", new Integer(appEvent.getType()));
177 
178            osxStartup.showError(message, error, false);
179        }
180    }
181 
182    public void handleOpenFile(File file) {
183        try {
184            waitForInitialisationFinished();
185            setFileToBeOpened(file);
186        } catch (Throwable error) {
187            String message = LocaleTools.instance().getMessage(
188                    "errors.cannotProcessApplicationEvent", new Integer(0));
189 
190            startup.showError(message, error, false);
191        }
192    }
193 
194    private void waitForInitialisationFinished() {
195        int timeout = INITIALIZATION_TIMEOUT;
196 
197        assert WAITING_FOR_INITIALITATION_LOG_INTERVAL % TICK == 0;
198 
199        while (!initailisationFinished && (timeout > 0)) {
200            if ((timeout % WAITING_FOR_INITIALITATION_LOG_INTERVAL) == 0) {
201                startupTools.logDuration("waiting for initialization to be finished before processing event");
202            }
203            try {
204                timeout -= TICK;
205                Thread.sleep(TICK);
206            } catch (InterruptedException interruption) {
207                PrintStream warnStream = System.err;
208 
209                warnStream.println("cannot wait for initialization to be finished: " + interruption);
210            }
211        }
212        if (timeout <= 0) {
213            throw new IllegalStateException("timeout while waiting to be ready for events");
214        }
215    }
216}

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