EMMA Coverage Report (generated Sat Oct 08 11:41:37 CEST 2011)
[all classes][net.sf.jomic.common]

COVERAGE SUMMARY FOR SOURCE FILE [Settings.java]

nameclass, %method, %block, %line, %
Settings.java100% (1/1)65%  (40/62)70%  (798/1133)75%  (198.7/265)

COVERAGE BREAKDOWN BY CLASS AND METHOD

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

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