File Source: Theme.java
/*
P/P * Method: com.dmdirc.ui.themes.Theme__static_init
*/
1 /*
2 * Copyright (c) 2006-2009 Chris Smith, Shane Mc Cormack, Gregory Holmes
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23 package com.dmdirc.ui.themes;
24
25 import com.dmdirc.config.IdentityManager;
26 import com.dmdirc.config.InvalidIdentityFileException;
27 import com.dmdirc.logger.ErrorLevel;
28 import com.dmdirc.logger.Logger;
29 import com.dmdirc.util.ConfigFile;
30 import com.dmdirc.util.InvalidConfigFileException;
31 import com.dmdirc.util.resourcemanager.ZipResourceManager;
32
33 import java.io.File;
34 import java.io.IOException;
35 import java.io.InputStream;
36
37 /**
38 * Represents one theme file.
39 *
40 * @author Chris
41 */
/*
P/P * Method: int compareTo(Object)
*
* Preconditions:
* this.file != null
* init'ed(this.metadata)
* x0 != null
* x0.file != null
* init'ed(x0.metadata)
* (soft) init'ed(this.metadata.automake)
* (soft) this.metadata.domains != null
* (soft) this.metadata.keydomains != null
* (soft) init'ed(x0.metadata.automake)
* (soft) x0.metadata.domains != null
* ...
*
* Postconditions:
* init'ed(return_value)
*/
42 public class Theme implements Comparable<Theme> {
43
44 /** The file to load the theme from. */
45 private final File file;
46
47 /** The config file containing theme meta-data. */
48 private ConfigFile metadata;
49
50 /** The resource manager we're using for this theme. */
51 private ZipResourceManager rm;
52
53 /** Whether or not this theme is enabled. */
54 private boolean enabled;
55
56 /** The Identity we've registered. */
57 private ThemeIdentity identity;
58
59 /**
60 * Creates a new instance of Theme.
61 *
62 * @param file The file to load the theme from
63 */
/*
P/P * Method: void com.dmdirc.ui.themes.Theme(File)
*
* Postconditions:
* this.file == file
* init'ed(this.file)
*/
64 public Theme(final File file) {
65 this.file = file;
66 }
67
68 /**
69 * Determines if this theme is valid or not (i.e., it is a valid zip file,
70 * and it contains one file).
71 *
72 * @return True if the theme is valid, false otherwise
73 */
74 public boolean isValidTheme() {
/*
P/P * Method: bool isValidTheme()
*
* Preconditions:
* init'ed(this.rm)
* (soft) this.file != null
* (soft) this.rm.zipFile != null
*
* Presumptions:
* init'ed(com.dmdirc.logger.ErrorLevel.MEDIUM)
*
* Postconditions:
* init'ed(return_value)
* this.metadata == One-of{old this.metadata, &new ConfigFile(isValidTheme#2), null}
* possibly_updated(this.metadata.lines)
* this.rm == One-of{old this.rm, &new ZipResourceManager(getInstance#1)}
* init'ed(this.rm)
* new ArrayList(ConfigFile#1) num objects <= 1
* new ArrayList(ZipResourceManager#2) num objects <= 1
* new ArrayList(readLines#4) num objects == 0
* new ConfigFile(isValidTheme#2) num objects <= 1
* init'ed(new ConfigFile(isValidTheme#2).charset)
* ...
*
* Test Vectors:
* this.rm: Inverse{null}, Addr_Set{null}
*/
75 if (rm == null) {
76 try {
77 rm = ZipResourceManager.getInstance(file.getCanonicalPath());
78 } catch (IOException ex) {
79 Logger.userError(ErrorLevel.MEDIUM, "I/O error when loading theme: "
80 + file.getAbsolutePath() + ": " + ex.getMessage());
81
82 return false;
83 }
84
85 if (rm != null && rm.resourceExists("theme.config")) {
86 metadata = new ConfigFile(rm.getResourceInputStream("theme.config"));
87
88 try {
89 metadata.read();
90 } catch (IOException ex) {
91 metadata = null;
92 } catch (InvalidConfigFileException ex) {
93 metadata = null;
94 }
95 }
96 }
97
98 return rm != null && rm.resourceExists("config");
99 }
100
101 /**
102 * Applies this theme to the client.
103 */
104 public void applyTheme() {
/*
P/P * Method: void applyTheme()
*
* Preconditions:
* (soft) init'ed(this.enabled)
* (soft) init'ed(this.rm)
* (soft) this.file != null
* (soft) this.rm.zipFile != null
*
* Presumptions:
* init'ed(com.dmdirc.logger.ErrorLevel.MEDIUM)
* this.rm.zipFile@105 != null
*
* Postconditions:
* init'ed(this.enabled)
* this.identity == One-of{old this.identity, &new ThemeIdentity(applyTheme#1)}
* this.metadata == One-of{old this.metadata, &new ConfigFile(isValidTheme#2), null}
* init'ed(this.metadata.lines)
* this.rm == One-of{old this.rm, &new ZipResourceManager(getInstance#1)}
* init'ed(this.rm)
* new ArrayList(ConfigFile#1) num objects <= 1
* new ConfigFile(isValidTheme#2) num objects == new ArrayList(ConfigFile#1) num objects
* new HashMap(ConfigFile#3) num objects == new ArrayList(ConfigFile#1) num objects
* new HashMap(MapList#1) num objects == new ArrayList(ConfigFile#1) num objects
* ...
*
* Test Vectors:
* this.enabled: {0}, {1}
*/
105 if (!isValidTheme() || rm == null || enabled) {
106 return;
107 }
108
109 enabled = true;
110
111 final InputStream stream = rm.getResourceInputStream("config");
112
113 if (stream != null) {
114 try {
115 identity = new ThemeIdentity(stream, this);
116 IdentityManager.addIdentity(identity);
117 } catch (InvalidIdentityFileException ex) {
118 Logger.userError(ErrorLevel.MEDIUM, "Error loading theme identity file: "
119 + ex.getMessage());
120 } catch (IOException ex) {
121 Logger.userError(ErrorLevel.MEDIUM, "Error loading theme identity file: "
122 + ex.getMessage());
123 }
124 }
125 }
126
127 /**
128 * Removes the effects of this theme.
129 */
130 public void removeTheme() {
/*
P/P * Method: void removeTheme()
*
* Preconditions:
* init'ed(this.rm)
* (soft) init'ed(this.enabled)
* (soft) this.file != null
* (soft) init'ed(this.identity)
* (soft) this.rm.zipFile != null
*
* Postconditions:
* init'ed(this.enabled)
* this.metadata == One-of{old this.metadata, &new ConfigFile(isValidTheme#2), null}
* init'ed(this.metadata.lines)
* this.rm == One-of{old this.rm, &new ZipResourceManager(getInstance#1)}
* init'ed(this.rm)
* new ArrayList(ConfigFile#1) num objects <= 1
* new ConfigFile(isValidTheme#2) num objects == new ArrayList(ConfigFile#1) num objects
* new HashMap(ConfigFile#3) num objects == new ArrayList(ConfigFile#1) num objects
* new HashMap(MapList#1) num objects == new ArrayList(ConfigFile#1) num objects
* new MapList(ConfigFile#2) num objects == new ArrayList(ConfigFile#1) num objects
* ...
*
* Test Vectors:
* this.enabled: {0}, {1}
* this.identity: Inverse{null}, Addr_Set{null}
*/
131 if (!isValidTheme() || !enabled || identity == null) {
132 return;
133 }
134
135 enabled = false;
136
137 IdentityManager.removeIdentity(identity);
138 }
139
140 /**
141 * Determines if this theme is enabled or not.
142 *
143 * @return True if the theme is enabled, false otherwise.
144 */
145 public boolean isEnabled() {
/*
P/P * Method: bool isEnabled()
*
* Preconditions:
* init'ed(this.enabled)
*
* Postconditions:
* return_value == this.enabled
* init'ed(return_value)
*/
146 return enabled;
147 }
148
149 /**
150 * Retrieves the name of this theme.
151 *
152 * @param includeExtension Whether or not to include the file extension
153 * @return This theme's name
154 */
155 public String getFileName(final boolean includeExtension) {
/*
P/P * Method: String getFileName(bool)
*
* Preconditions:
* this.file != null
*
* Presumptions:
* java.io.File:getName(...)@156 != null
*
* Postconditions:
* java.lang.String:substring(...)._tainted == 0
* return_value != null
*
* Test Vectors:
* includeExtension: {1}, {0}
*/
156 String result = file.getName();
157
158 if (!includeExtension) {
159 result = result.substring(0, result.length() - 4);
160 }
161
162 return result;
163 }
164
165 /**
166 * Retrieves the name of this theme.
167 *
168 * @return This theme's name, with file extension
169 */
170 public String getFileName() {
/*
P/P * Method: String getFileName()
*
* Preconditions:
* this.file != null
*
* Postconditions:
* java.lang.String:substring(...)._tainted == 0
* return_value != null
*/
171 return getFileName(true);
172 }
173
174 /**
175 * Retrieves the name of this theme.
176 *
177 * @return This theme's name
178 */
179 public String getName() {
/*
P/P * Method: String getName()
*
* Preconditions:
* this.file != null
* init'ed(this.metadata)
* (soft) init'ed(this.metadata.automake)
* (soft) this.metadata.domains != null
* (soft) this.metadata.keydomains != null
*
* Postconditions:
* java.lang.String:substring(...)._tainted == 0
* init'ed(return_value)
*/
180 return getMetaData("name", getFileName(false));
181 }
182
183 /**
184 * Retrieves the version of this theme.
185 *
186 * @return This theme's version
187 */
188 public String getVersion() {
/*
P/P * Method: String getVersion()
*
* Preconditions:
* init'ed(this.metadata)
* (soft) init'ed(this.metadata.automake)
* (soft) this.metadata.domains != null
* (soft) this.metadata.keydomains != null
*
* Postconditions:
* init'ed(return_value)
*/
189 return getMetaData("version", "?");
190 }
191
192 /**
193 * Retrieves the author of this theme.
194 *
195 * @return This theme's author
196 */
197 public String getAuthor() {
/*
P/P * Method: String getAuthor()
*
* Preconditions:
* init'ed(this.metadata)
* (soft) init'ed(this.metadata.automake)
* (soft) this.metadata.domains != null
* (soft) this.metadata.keydomains != null
*
* Postconditions:
* init'ed(return_value)
*/
198 return getMetaData("author", "?");
199 }
200
201 /**
202 * Retrieves the description of this theme.
203 *
204 * @return This theme's description
205 */
206 public String getDescription() {
/*
P/P * Method: String getDescription()
*
* Preconditions:
* init'ed(this.metadata)
* (soft) init'ed(this.metadata.automake)
* (soft) this.metadata.domains != null
* (soft) this.metadata.keydomains != null
*
* Postconditions:
* init'ed(return_value)
*/
207 return getMetaData("description", "?");
208 }
209
210 /** {@inheritDoc} */
211 @Override
212 public int compareTo(final Theme o) {
/*
P/P * Method: int compareTo(Theme)
*
* Preconditions:
* o != null
* o.file != null
* init'ed(o.metadata)
* this.file != null
* init'ed(this.metadata)
* (soft) init'ed(o.metadata.automake)
* (soft) o.metadata.domains != null
* (soft) o.metadata.keydomains != null
* (soft) init'ed(this.metadata.automake)
* (soft) this.metadata.domains != null
* ...
*
* Postconditions:
* init'ed(return_value)
*/
213 return getName().compareTo(o.getName());
214 }
215
216 /**
217 * Attempts to read the specified key from the 'data' keysection of the
218 * theme's config file.
219 *
220 * @param key The key to be read
221 * @param fallback The value to use if the file, section or entry doesn't
222 * exist
223 * @return The relevant meta-data, or the fallback value
224 */
225 private String getMetaData(final String key, final String fallback) {
/*
P/P * Method: String getMetaData(String, String)
*
* Preconditions:
* init'ed(this.metadata)
* (soft) init'ed(this.metadata.automake)
* (soft) this.metadata.domains != null
* (soft) this.metadata.keydomains != null
*
* Presumptions:
* java.util.Map:get(...)@236 != null
*
* Postconditions:
* init'ed(return_value)
*
* Test Vectors:
* this.metadata: Addr_Set{null}, Inverse{null}
* java.util.Map:containsKey(...)@226: {1}, {0}
* java.util.Map:containsKey(...)@267: {0}, {1}
*/
226 if (metadata == null || !metadata.isKeyDomain("data") ||
227 !metadata.getKeyDomain("data").containsKey(key)) {
228 return fallback;
229 }
230
231 return metadata.getKeyDomain("data").get(key);
232 }
233
234 }
SofCheck Inspector Build Version : 2.17854
| Theme.java |
2009-Jun-25 01:54:24 |
| Theme.class |
2009-Sep-02 17:04:15 |