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

COVERAGE SUMMARY FOR SOURCE FILE [Settings.java]

nameclass, %method, %block, %line, %
Settings.java100% (1/1)67%  (42/63)71%  (839/1175)74%  (205.6/278)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Settings100% (1/1)67%  (42/63)71%  (839/1175)74%  (205.6/278)
getArchiveCache (): File 0%   (0/1)0%   (0/4)0%   (0/1)
getBlurMode (): String 0%   (0/1)0%   (0/7)0%   (0/1)
getFew (): int 0%   (0/1)0%   (0/4)0%   (0/1)
getLastExportAllImagesDir (): File 0%   (0/1)0%   (0/4)0%   (0/1)
getLastExportedImageDir (): File 0%   (0/1)0%   (0/4)0%   (0/1)
getOpenNewComic (): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
resetComicFrame (): void 0%   (0/1)0%   (0/4)0%   (0/2)
setAdjustArchiveSuffix (boolean): void 0%   (0/1)0%   (0/5)0%   (0/2)
setBlurMode (String): void 0%   (0/1)0%   (0/8)0%   (0/2)
setBlurRadius (int): void 0%   (0/1)0%   (0/7)0%   (0/2)
setBlurThreshold (int): void 0%   (0/1)0%   (0/7)0%   (0/2)
setLastCreateComicSourceDir (File): void 0%   (0/1)0%   (0/13)0%   (0/3)
setLastCreateComicTargetDir (File): void 0%   (0/1)0%   (0/13)0%   (0/3)
setLastExportAllImagesDir (File): void 0%   (0/1)0%   (0/13)0%   (0/3)
setLastExportedImageDir (File): void 0%   (0/1)0%   (0/13)0%   (0/3)
setOpenInFullScreen (boolean): void 0%   (0/1)0%   (0/5)0%   (0/2)
setOpenNewComic (boolean): void 0%   (0/1)0%   (0/5)0%   (0/2)
setShowInfo (boolean): void 0%   (0/1)0%   (0/5)0%   (0/2)
setShowThumbs (boolean): void 0%   (0/1)0%   (0/5)0%   (0/2)
setShowToolbar (boolean): void 0%   (0/1)0%   (0/5)0%   (0/2)
setUseBlur (boolean): void 0%   (0/1)0%   (0/5)0%   (0/2)
propertyChange (PropertyChangeEvent): void 100% (1/1)64%  (18/28)69%  (5.5/8)
getRecentFiles (): List 100% (1/1)67%  (8/12)78%  (1.6/2)
addRecentFile (File, int): void 100% (1/1)67%  (55/82)67%  (9.4/14)
setupBaseCacheDir (String): void 100% (1/1)67%  (62/92)66%  (10.6/16)
applyComicWindow (Component): void 100% (1/1)69%  (9/13)83%  (2.5/3)
setMostRecentPage (int): void 100% (1/1)69%  (9/13)83%  (2.5/3)
clearRecentFiles (): void 100% (1/1)71%  (12/17)92%  (3.7/4)
setLocale (String): void 100% (1/1)71%  (10/14)83%  (2.5/3)
read (File): void 100% (1/1)72%  (58/81)87%  (18.2/21)
getCacheDir (String): File 100% (1/1)75%  (51/68)83%  (9.9/12)
write (File): void 100% (1/1)75%  (27/36)92%  (8.3/9)
<static initializer> 100% (1/1)80%  (12/15)80%  (0.8/1)
getMostRecentFile (): File 100% (1/1)83%  (25/30)91%  (6.4/7)
Settings (): void 100% (1/1)84%  (205/245)83%  (45.8/55)
updateRecentFilesFromProperties (): void 100% (1/1)85%  (61/72)91%  (21/23)
Settings (Properties): void 100% (1/1)100% (28/28)100% (9/9)
getAdjustArchiveSuffix (): boolean 100% (1/1)100% (4/4)100% (1/1)
getArchiveCacheSizeInMb (): int 100% (1/1)100% (4/4)100% (1/1)
getBlurRadius (): int 100% (1/1)100% (6/6)100% (1/1)
getBlurThreshold (): int 100% (1/1)100% (6/6)100% (1/1)
getCacheDir (): File 100% (1/1)100% (5/5)100% (2/2)
getImageIOCache (): File 100% (1/1)100% (4/4)100% (1/1)
getLastCreateComicSourceDir (): File 100% (1/1)100% (4/4)100% (1/1)
getLastCreateComicTargetDir (): File 100% (1/1)100% (4/4)100% (1/1)
getLocale (): String 100% (1/1)100% (6/6)100% (2/2)
getMostRecentPage (): int 100% (1/1)100% (4/4)100% (1/1)
getOpenInFullScreen (): boolean 100% (1/1)100% (4/4)100% (1/1)
getRecentCount (): int 100% (1/1)100% (4/4)100% (1/1)
getScrollCount (): int 100% (1/1)100% (4/4)100% (1/1)
getSettingsFile (): File 100% (1/1)100% (5/5)100% (1/1)
getShowInfo (): boolean 100% (1/1)100% (4/4)100% (1/1)
getShowThumbs (): boolean 100% (1/1)100% (4/4)100% (1/1)
getShowToolbar (): boolean 100% (1/1)100% (4/4)100% (1/1)
getSortMode (): String 100% (1/1)100% (4/4)100% (1/1)
getTileCacheSizeInMb (): int 100% (1/1)100% (4/4)100% (1/1)
getUnrarCommand (): String 100% (1/1)100% (4/4)100% (1/1)
instance (): Settings 100% (1/1)100% (8/8)100% (3/3)
removeDuplicatesFromRecentFiles (): void 100% (1/1)100% (44/44)100% (9/9)
setComicWindow (Component): void 100% (1/1)100% (5/5)100% (2/2)
setupBaseCacheDir (): void 100% (1/1)100% (6/6)100% (2/2)
updatePropertiesFromRecentFiles (): void 100% (1/1)100% (34/34)100% (9/9)
useBlur (): boolean 100% (1/1)100% (4/4)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.common;
17 
18import java.awt.Component;
19import java.awt.Dimension;
20import java.awt.Toolkit;
21import java.beans.PropertyChangeEvent;
22import java.beans.PropertyChangeListener;
23import java.io.File;
24import java.io.FileInputStream;
25import java.io.FileNotFoundException;
26import java.io.FileOutputStream;
27import java.io.IOException;
28import java.io.InputStream;
29import java.io.OutputStream;
30import java.util.ArrayList;
31import java.util.HashMap;
32import java.util.Iterator;
33import java.util.List;
34import java.util.Locale;
35import java.util.Map;
36import java.util.Properties;
37import java.util.Set;
38 
39import net.roydesign.mac.MRJAdapter;
40import net.roydesign.mac.MRJFolderConstants;
41import net.sf.jomic.tools.FileTools;
42import net.sf.jomic.tools.ImageTools;
43import net.sf.jomic.tools.LocaleTools;
44import net.sf.jomic.tools.StringTools;
45import net.sf.jomic.tools.SystemTools;
46import net.sf.jomic.tools.TunneledIOException;
47import net.sf.wraplog.Logger;
48 
49/**
50 *  Settings for Jomic. These are collected as Properties, and can be read from or written to a
51 *  settings file.
52 *
53 * @author    Thomas Aglassinger
54 * @see       #read(File)
55 * @see       #write(File)
56 */
57public final class Settings extends ComicSheetRenderSettings implements PropertyChangeListener
58{
59    public static final int MAX_BLUR_RADIUS = 15;
60    public static final int MAX_BLUR_THRESHOLD = 255;
61    public static final int MIN_BLUR_RADIUS = 3;
62    public static final int MIN_BLUR_THRESHOLD = 0;
63 
64    private static final double DEFAULT_HEIGHT_FACTOR = 0.5;
65    private static final double DEFAULT_WIDTH_FACTOR = 0.5;
66 
67    private static Settings instance;
68 
69    private File baseCacheDir;
70 
71    /**
72     *  Map to map cache name (for example "imageio") to directory (for example
73     *  "~/Users/me/Library/Cache/jomic/imageio").
74     *
75     * @see    #getCacheDir(String)
76     */
77    private Map cacheDirMap;
78    private String defaultUnrar;
79    private FileTools fileTools;
80    private ImageTools imageTools;
81    private LocaleTools localeTools;
82    private Logger logger;
83    private List recentFiles;
84    private StartupTools startupTools;
85    private StringTools stringTools;
86    private SystemTools systemTools;
87 
88    public Settings(Properties defaults) {
89        this();
90 
91        Iterator defaultsRider = defaults.entrySet().iterator();
92 
93        while (defaultsRider.hasNext()) {
94            Map.Entry entry = (Map.Entry) defaultsRider.next();
95            String key = (String) entry.getKey();
96            String value = (String) entry.getValue();
97 
98            setProperty(key, value);
99        }
100    }
101 
102    private Settings() {
103        logger = Logger.getLogger(Settings.class);
104        fileTools = FileTools.instance();
105        imageTools = ImageTools.instance();
106        localeTools = LocaleTools.instance();
107        startupTools = StartupTools.instance();
108        stringTools = StringTools.instance();
109        systemTools = SystemTools.instance();
110 
111        setSystemPropertyPrefix(PropertyConstants.SYSTEM_PROPERTY_PREFIX);
112        setDefault(PropertyConstants.USE_UNRAR_RESOURCE, false);
113        defaultUnrar = getProperty(PropertyConstants.UNRAR);
114        if (defaultUnrar == null) {
115            boolean useUnrarResource = getBooleanProperty(PropertyConstants.USE_UNRAR_RESOURCE);
116 
117            if (useUnrarResource) {
118                try {
119                    defaultUnrar = MRJAdapter.getBundleResource("unrar").getAbsolutePath();
120                } catch (FileNotFoundException error) {
121                    String message = localeTools.getMessage("errors.unrarMustBeInResourceFolder");
122 
123                    logger.error(message, error);
124                    throw new IllegalStateException(message);
125                }
126            } else {
127                // rely on user to install proper version
128                defaultUnrar = PropertyConstants.DEFAULT_UNRAR;
129            }
130        }
131 
132        // Setup default properties
133        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
134        int[] defaultComicWindow = new int[]{
135                0, 0,
136                (int) (DEFAULT_WIDTH_FACTOR * screenSize.width),
137                (int) (DEFAULT_HEIGHT_FACTOR * screenSize.height)
138                };
139        String homeDir = System.getProperty("user.home");
140 
141        assert homeDir != null;
142 
143        setDefault(PropertyConstants.ARCHIVE_CACHE_SIZE_IN_MB,
144                PropertyConstants.DEFAULT_ARCHIVE_CACHE_SIZE_IN_MB);
145        setDefault(PropertyConstants.BLUR_RADIUS, PropertyConstants.DEFAULT_BLUR_RADIUS);
146        setDefault(PropertyConstants.BLUR_THRESHOLD, PropertyConstants.DEFAULT_BLUR_THRESHOLD);
147        setDefault(PropertyConstants.BLUR_MODE, ImageTools.DIFFERENCE_BLUR);
148        setDefault(PropertyConstants.COMIC_WINDOW, stringTools.arrayToString(defaultComicWindow));
149        setDefault(PropertyConstants.FEW, PropertyConstants.DEFAULT_FEW);
150        setDefault(PropertyConstants.LAST_CREATE_COMIC_SOURCE_DIR, "");
151        setDefault(PropertyConstants.LAST_CREATE_COMIC_TARGET_DIR, homeDir);
152        setDefault(PropertyConstants.LAST_EXPORTED_IMAGE_DIR, homeDir);
153        setDefault(PropertyConstants.LAST_EXPORT_ALL_IMAGES_DIR, homeDir);
154        setDefault(PropertyConstants.LOCALE, Locale.getDefault().toString());
155        setDefault(PropertyConstants.MOST_RECENT_PAGE, PropertyConstants.DEFAULT_MOST_RECENT_PAGE);
156        setDefault(PropertyConstants.OPEN_IN_FULL_SCREEN, false);
157        setDefault(PropertyConstants.RECENT_COUNT, PropertyConstants.DEFAULT_RECENT_COUNT);
158        setDefault(PropertyConstants.SCROLL_COUNT, PropertyConstants.DEFAULT_SCROLL_COUNT);
159        setDefault(PropertyConstants.SHOW_INFO, false);
160        setDefault(PropertyConstants.SHOW_TOOLBAR, true);
161        setDefault(PropertyConstants.SHOW_THUMBS, false);
162        setDefault(PropertyConstants.SORT_MODE, PropertyConstants.DEFAULT_SORT_MODE);
163        setDefault(ComicSheetRenderSettings.SWAP_LEFT_AND_RIGHT_IMAGE, false);
164        setDefault(PropertyConstants.TEST_DELAY, PropertyConstants.DEFAULT_DELAY);
165        setDefault(PropertyConstants.TILE_CACHE_SIZE_IN_MB, PropertyConstants.DEFAULT_TILE_CACHE_SIZE_IN_MB);
166        setDefault(ComicSheetRenderSettings.SHOW_TWO_PAGES, false);
167        setDefault(PropertyConstants.UNRAR, defaultUnrar);
168 
169        recentFiles = new ArrayList();
170        cacheDirMap = new HashMap();
171        addPropertyChangeListener(localeTools);
172        addPropertyChangeListener(PropertyConstants.CACHE_DIR, this);
173        localeTools.setLocale(getLocale());
174    }
175 
176    public void setAdjustArchiveSuffix(boolean newAdjustArchiveSuffix) {
177        setBooleanProperty(PropertyConstants.ADJUST_ARCHIVE_SUFFIX, newAdjustArchiveSuffix);
178    }
179 
180    public void setBlurMode(String newBlurMode) {
181        setChoiceProperty(PropertyConstants.BLUR_MODE, newBlurMode, imageTools.getPossibleBlurModes());
182    }
183 
184    public void setBlurRadius(int newBlurRadius) {
185        setLimitedIntProperty(PropertyConstants.BLUR_RADIUS, newBlurRadius, MIN_BLUR_RADIUS, MAX_BLUR_RADIUS);
186    }
187 
188    public void setBlurThreshold(int newBlurThreshold) {
189        setLimitedIntProperty(PropertyConstants.BLUR_THRESHOLD, newBlurThreshold,
190                MIN_BLUR_THRESHOLD, MAX_BLUR_THRESHOLD);
191    }
192 
193    public void setComicWindow(Component component) {
194        setComponentAreaProperty(PropertyConstants.COMIC_WINDOW, component);
195    }
196 
197    public void setLastCreateComicSourceDir(File newSourceDir) {
198        assert newSourceDir != null;
199        setFileProperty(PropertyConstants.LAST_CREATE_COMIC_SOURCE_DIR, newSourceDir);
200    }
201 
202    public void setLastCreateComicTargetDir(File newTargetDir) {
203        assert newTargetDir != null;
204        setFileProperty(PropertyConstants.LAST_CREATE_COMIC_TARGET_DIR, newTargetDir);
205    }
206 
207    public void setLastExportAllImagesDir(File newDir) {
208        assert newDir != null;
209        setFileProperty(PropertyConstants.LAST_EXPORT_ALL_IMAGES_DIR, newDir);
210    }
211 
212    public void setLastExportedImageDir(File newImageDir) {
213        assert newImageDir != null;
214        setFileProperty(PropertyConstants.LAST_EXPORTED_IMAGE_DIR, newImageDir);
215    }
216 
217    public void setLocale(String newLocale) {
218        assert newLocale != null;
219        setProperty(PropertyConstants.LOCALE, newLocale);
220    }
221 
222    /**
223     *  Get the most recently opened file, or <code>null</code> no recent file has ever been opened
224     *  (typically when using Jomic the first time after installation).
225     */
226    public void setMostRecentPage(int newMostRecentPage) {
227        assert newMostRecentPage >= 0;
228        setIntProperty(PropertyConstants.MOST_RECENT_PAGE, newMostRecentPage);
229    }
230 
231    public void setOpenInFullScreen(boolean newOpenInFullScreen) {
232        setBooleanProperty(PropertyConstants.OPEN_IN_FULL_SCREEN, newOpenInFullScreen);
233    }
234 
235    public void setOpenNewComic(boolean newOpenNewComic) {
236        setBooleanProperty(PropertyConstants.OPEN_NEW_COMIC, newOpenNewComic);
237    }
238 
239    public void setShowInfo(boolean newShowInfo) {
240        setBooleanProperty(PropertyConstants.SHOW_INFO, newShowInfo);
241    }
242 
243    public void setShowThumbs(boolean newShowThumbs) {
244        setBooleanProperty(PropertyConstants.SHOW_THUMBS, newShowThumbs);
245    }
246 
247    public void setShowToolbar(boolean newShowToolbar) {
248        setBooleanProperty(PropertyConstants.SHOW_TOOLBAR, newShowToolbar);
249    }
250 
251    public void setUseBlur(boolean newUseBlur) {
252        setBooleanProperty(PropertyConstants.USE_BLUR, newUseBlur);
253    }
254 
255    private synchronized void setupBaseCacheDir()
256        throws FileNotFoundException {
257        setupBaseCacheDir(getProperty(PropertyConstants.CACHE_DIR));
258    }
259 
260    private synchronized void setupBaseCacheDir(String cacheDirName)
261        throws FileNotFoundException {
262        if (cacheDirName != null) {
263            baseCacheDir = new File(cacheDirName);
264        } else {
265            if (systemTools.isMacOSX()) {
266                try {
267                    baseCacheDir = MRJAdapter.findFolder(MRJFolderConstants.kUserDomain,
268                            MRJFolderConstants.kCachedDataFolderType, true);
269                } catch (FileNotFoundException error) {
270                    String message = localeTools.getMessage("errors.cannotCreateCacheFolder");
271 
272                    throw new TunneledIOException(message, error);
273                }
274                baseCacheDir = new File(baseCacheDir.getAbsolutePath(), "jomic");
275            } else {
276                File jomicDir = new File(System.getProperty("user.home"), ".jomic");
277 
278                baseCacheDir = new File(jomicDir, "caches");
279            }
280        }
281        if (logger.isInfoEnabled()) {
282            logger.info("base cache path = "
283                    + stringTools.sourced(baseCacheDir.getAbsolutePath()));
284        }
285        assert baseCacheDir != null;
286        fileTools.mkdirs(baseCacheDir);
287    }
288 
289    public boolean getAdjustArchiveSuffix() {
290        return getBooleanProperty(PropertyConstants.ADJUST_ARCHIVE_SUFFIX);
291    }
292 
293    public File getArchiveCache()
294        throws IOException {
295        return getCacheDir("archives");
296    }
297 
298    /**
299     *  Get tile cache size (in mega byte).
300     */
301    public int getArchiveCacheSizeInMb() {
302        return getIntProperty(PropertyConstants.ARCHIVE_CACHE_SIZE_IN_MB);
303    }
304 
305    public String getBlurMode() {
306        return getChoiceProperty(PropertyConstants.BLUR_MODE, imageTools.getPossibleBlurModes());
307    }
308 
309    public int getBlurRadius() {
310        return getLimitedIntProperty(PropertyConstants.BLUR_RADIUS, MIN_BLUR_RADIUS, MAX_BLUR_RADIUS);
311    }
312 
313    public int getBlurThreshold() {
314        return getLimitedIntProperty(PropertyConstants.BLUR_THRESHOLD, MIN_BLUR_THRESHOLD, MAX_BLUR_THRESHOLD);
315    }
316 
317    /**
318     *  Get the cache directory <code>name</code> in the base cache diretory. If the directory does
319     *  not exist yet, create it.
320     */
321    public File getCacheDir(String name)
322        throws FileNotFoundException {
323        assert name != null;
324        assert name.length() > 0;
325        File result;
326 
327        synchronized (cacheDirMap) {
328            result = (File) cacheDirMap.get(name);
329            if (result == null) {
330                setupBaseCacheDir();
331                result = new File(baseCacheDir, name);
332                fileTools.mkdirs(result);
333                cacheDirMap.put(name, result);
334            }
335        }
336        assert result != null;
337        return result;
338    }
339 
340    /**
341     *  Get the base cache directory, where all the caches are stored.
342     */
343    public File getCacheDir()
344        throws FileNotFoundException {
345        setupBaseCacheDir();
346        return baseCacheDir;
347    }
348 
349    public int getFew() {
350        return getIntProperty(PropertyConstants.FEW);
351    }
352 
353    public File getImageIOCache()
354        throws IOException {
355        return getCacheDir("imageio");
356    }
357 
358    public File getLastCreateComicSourceDir() {
359        return getFileProperty(PropertyConstants.LAST_CREATE_COMIC_SOURCE_DIR);
360    }
361 
362    public File getLastCreateComicTargetDir() {
363        return getFileProperty(PropertyConstants.LAST_CREATE_COMIC_TARGET_DIR);
364    }
365 
366    public File getLastExportAllImagesDir() {
367        return getFileProperty(PropertyConstants.LAST_EXPORT_ALL_IMAGES_DIR);
368    }
369 
370    public File getLastExportedImageDir() {
371        return getFileProperty(PropertyConstants.LAST_EXPORTED_IMAGE_DIR);
372    }
373 
374    public String getLocale() {
375        String result = getProperty(PropertyConstants.LOCALE);
376 
377        return result;
378    }
379 
380    /**
381     *  Get the most recently opened file, or <code>null</code> no recent file has ever been opened
382     *  (typically when using Jomic the first time after installation).
383     */
384    public File getMostRecentFile() {
385        File result;
386 
387        synchronized (recentFiles) {
388            int fileCount = getRecentFiles().size();
389 
390            if (fileCount == 0) {
391                result = null;
392            } else {
393                result = (File) getRecentFiles().get(0);
394            }
395        }
396        return result;
397    }
398 
399    /**
400     *  Get the most recently opened file, or <code>null</code> no recent file has ever been opened
401     *  (typically when using Jomic the first time after installation).
402     */
403    public int getMostRecentPage() {
404        return getIntProperty(PropertyConstants.MOST_RECENT_PAGE);
405    }
406 
407    public boolean getOpenInFullScreen() {
408        return getBooleanProperty(PropertyConstants.OPEN_IN_FULL_SCREEN);
409    }
410 
411    public boolean getOpenNewComic() {
412        return getBooleanProperty(PropertyConstants.OPEN_NEW_COMIC);
413    }
414 
415    public int getRecentCount() {
416        return getIntProperty(PropertyConstants.RECENT_COUNT);
417    }
418 
419    public List getRecentFiles() {
420        assert recentFiles != null;
421        return recentFiles;
422    }
423 
424    public int getScrollCount() {
425        return getIntProperty(PropertyConstants.SCROLL_COUNT);
426    }
427 
428    /**
429     *  Gets the file where the settings are stored.
430     */
431    public File getSettingsFile() {
432        return startupTools.getSettingsFile("jomic");
433    }
434 
435    public boolean getShowInfo() {
436        return getBooleanProperty(PropertyConstants.SHOW_INFO);
437    }
438 
439    public boolean getShowThumbs() {
440        return getBooleanProperty(PropertyConstants.SHOW_THUMBS);
441    }
442 
443    public boolean getShowToolbar() {
444        return getBooleanProperty(PropertyConstants.SHOW_TOOLBAR);
445    }
446 
447    public String getSortMode() {
448        return getProperty(PropertyConstants.SORT_MODE);
449    }
450 
451    /**
452     *  Get tile cache size (in mega byte).
453     */
454    public int getTileCacheSizeInMb() {
455        return getIntProperty(PropertyConstants.TILE_CACHE_SIZE_IN_MB);
456    }
457 
458    public String getUnrarCommand() {
459        return getProperty(PropertyConstants.UNRAR);
460    }
461 
462    public static synchronized Settings instance() {
463        if (instance == null) {
464            instance = new Settings();
465        }
466        return instance;
467    }
468 
469    public void addRecentFile(final File file, int page) {
470        assert file != null;
471        assert page >= 0;
472        if (logger.isDebugEnabled()) {
473            logger.debug("add recent file: \"" + file + "\" at page " + page);
474        }
475        synchronized (recentFiles) {
476            recentFiles.remove(file);
477            recentFiles.add(0, file);
478            setMostRecentPage(page);
479            if (recentFiles.size() > getRecentCount()) {
480                if (logger.isDebugEnabled()) {
481                    logger.debug("discarding oldest recent file");
482                }
483                recentFiles.remove(getRecentCount());
484            }
485        }
486    }
487 
488    public void applyComicWindow(Component component) {
489        assert component != null;
490        applyComponentAreaProperty(PropertyConstants.COMIC_WINDOW, component);
491    }
492 
493    public void clearRecentFiles() {
494        synchronized (recentFiles) {
495            recentFiles.clear();
496        }
497    }
498 
499    public void propertyChange(PropertyChangeEvent event) {
500        assert event != null;
501        String propertyName = event.getPropertyName();
502 
503        if (propertyName.equals(PropertyConstants.CACHE_DIR)) {
504            try {
505                setupBaseCacheDir((String) event.getNewValue());
506            } catch (FileNotFoundException error) {
507                throw new TunneledIOException(error);
508            }
509        }
510    }
511 
512    public void read(File file)
513        throws IOException {
514        assert file != null;
515        Properties loaded = new Properties();
516 
517        try {
518            InputStream in = new FileInputStream(file);
519 
520            try {
521                loaded.load(in);
522            } finally {
523                in.close();
524            }
525 
526            Set entries = loaded.entrySet();
527            Iterator rider = entries.iterator();
528 
529            while (rider.hasNext()) {
530                Map.Entry entry = (Map.Entry) rider.next();
531 
532                setProperty((String) entry.getKey(), (String) entry.getValue());
533            }
534            updateRecentFilesFromProperties();
535 
536            // Remove obsolete properties
537            remove("comic.height");
538            remove("comic.left");
539            remove("comic.top");
540            remove("comic.width");
541        } catch (FileNotFoundException error) {
542            logger.warn("cannot read settings from \"" + file + "\"; using defaults");
543        }
544    }
545 
546    public void resetComicFrame() {
547        remove(PropertyConstants.COMIC_WINDOW);
548    }
549 
550    public boolean useBlur() {
551        return getBooleanProperty(PropertyConstants.USE_BLUR);
552    }
553 
554    public void write(File settingsFile)
555        throws IOException {
556        assert settingsFile != null;
557 
558        // Make sure directories for settings file exist.
559        File settingsDir = settingsFile.getParentFile();
560 
561        fileTools.mkdirs(settingsDir);
562 
563        // Write actual settings file.
564        OutputStream out = new FileOutputStream(settingsFile);
565 
566        updatePropertiesFromRecentFiles();
567        try {
568            store(out, "Settings for Jomic");
569        } finally {
570            out.close();
571        }
572    }
573 
574    private void removeDuplicatesFromRecentFiles() {
575        recentFiles = new ArrayList();
576        for (int i = 0; i < getRecentCount(); i += 1) {
577            String key = PropertyConstants.RECENT_PREFIX + i;
578            String recentPath = getProperty(key);
579 
580            if (recentPath != null) {
581                File recentFile = new File(recentPath);
582 
583                if (!recentFiles.contains(recentFile)) {
584                    recentFiles.add(recentFile);
585                }
586            }
587        }
588    }
589 
590    private void updatePropertiesFromRecentFiles() {
591        setIntProperty(PropertyConstants.RECENT_COUNT, getRecentCount());
592 
593        int i = 1;
594        Iterator rider = recentFiles.iterator();
595 
596        while (rider.hasNext()) {
597            File recentFile = (File) rider.next();
598 
599            setProperty(PropertyConstants.RECENT_PREFIX + i, recentFile.getAbsolutePath());
600            i += 1;
601        }
602    }
603 
604    private void updateRecentFilesFromProperties() {
605        removeDuplicatesFromRecentFiles();
606 
607        // Remove "recent" properties.
608        Map.Entry recentEntryToRemove;
609 
610        do {
611            Set entries = entrySet();
612            Iterator rider = entries.iterator();
613 
614            // This property should never exist, and would cause trouble for substring-index operations later on.
615            if (getProperty(PropertyConstants.RECENT_PREFIX) != null) {
616                String message = localeTools.getMessage(
617                        "errors.propertyMustBeRemoved", PropertyConstants.RECENT_PREFIX);
618 
619                throw new IllegalStateException(message);
620            }
621 
622            recentEntryToRemove = null;
623            while ((recentEntryToRemove == null) && (rider.hasNext())) {
624                Map.Entry next = (Map.Entry) rider.next();
625                String propertyName = (String) next.getKey();
626 
627                if (propertyName.startsWith(PropertyConstants.RECENT_PREFIX)) {
628                    String suffix = propertyName.substring(PropertyConstants.RECENT_PREFIX.length());
629 
630                    try {
631                        Integer.parseInt(suffix);
632                        recentEntryToRemove = next;
633                    } catch (NumberFormatException error) {
634                        logger.debug("keeping non-numeric recent-property: {}", propertyName);
635                    }
636                }
637            }
638            if (recentEntryToRemove != null) {
639                String recentKeyToRemove = (String) recentEntryToRemove.getKey();
640 
641                remove(recentKeyToRemove);
642            }
643        } while (recentEntryToRemove != null);
644    }
645}

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