Statistics
| Revision:

root / trunk / frameworks / _fwAndami / src / com / iver / andami / iconthemes2 / IconThemeManager.java @ 15633

History | View | Annotate | Download (12.6 KB)

1
package com.iver.andami.iconthemes2;
2

    
3
import java.io.File;
4
import java.io.FileInputStream;
5
import java.io.FileNotFoundException;
6
import java.io.IOException;
7
import java.io.InputStream;
8
import java.util.ArrayList;
9
import java.util.Collection;
10
import java.util.Enumeration;
11
import java.util.Iterator;
12
import java.util.zip.ZipEntry;
13
import java.util.zip.ZipException;
14
import java.util.zip.ZipFile;
15

    
16
import org.kxml2.io.KXmlParser;
17
import org.xmlpull.v1.XmlPullParserException;
18

    
19
import com.iver.andami.Launcher;
20
import com.iver.andami.PluginServices;
21

    
22
/**
23
 * This class controls the icon theme. Contains two themes, the first is a default
24
 * theme and the second is the current theme. When it creates the class the default and
25
 * the current theme are the same. Allows change the current theme, register a new theme,
26
 * delete one,... and all the methods that the <code>Collection</code> interface contains.
27
 * The themes are stored in an ArrayList.
28
 *
29
 * @author eustaquio
30
 */
31
public class IconThemeManager implements Collection{
32

    
33
        private AbstractIconTheme def;
34
        private AbstractIconTheme current;
35
        private File themesDir = null;
36
        ArrayList<AbstractIconTheme> themes=new ArrayList<AbstractIconTheme>();
37
        private final String themeDefinitionFile = "theme.xml";
38

    
39

    
40
        /**
41
         * Default constructor. Creates a iconThemeMemory by default and assigns it
42
         * like default and current. The default theme is add to the themes ArrayList.
43
         */
44
        public IconThemeManager(){
45
                IconThemeMemory aux = new IconThemeMemory(null);
46
                def = aux;
47
                def.setName("Default");
48
                current = aux;
49
                themes.add(def);
50

    
51
        }
52

    
53
        /**
54
         * Gets the default theme
55
         * @return the default theme.
56
         */
57
        public AbstractIconTheme getDefault(){
58
                return def;
59
        }
60

    
61
        /**
62
         * Sets the iconTheme like current theme
63
         * @param iconTheme
64
         */
65
        public void setCurrent(AbstractIconTheme iconTheme){
66
                if(themes.contains(iconTheme)){
67
                        current = iconTheme;
68
                        //saveConfig(current);
69
                }else{
70
                        register(iconTheme);
71
                        current = iconTheme;
72
                        //saveConfig(current);
73
                }
74
        }
75

    
76
        /**
77
         * Gets the current theme
78
         * @return current the current theme
79
         */
80
        public AbstractIconTheme getCurrent(){
81
                return current;
82
        }
83

    
84
        /**
85
         * Stores a icon theme that receives like a parametre
86
         * @param iconTheme
87
         */
88
        public void register(AbstractIconTheme iconTheme){
89
                themes.add(iconTheme);
90
                iconTheme.setDefault(def);
91
        }
92

    
93
        /**
94
         * Returns the theme that has been registered with the name that receives like
95
         * parameter
96
         * @param themeName
97
         * @return the theme that contains like name in its properties the parameter
98
         */
99
        public AbstractIconTheme getTheme(String themeName){
100
                for(int i = 0; i<themes.size();i++){
101
                        if(themes.get(i).getName().equals(themeName)) return themes.get(i);
102
                }
103
                return null;
104
        }
105

    
106
        /**
107
         * Set the directory to read the icon themes.
108
         *
109
         * @param themesDir The directory in which the icon themes
110
         * are stored
111
         *
112
         * @throws FileNotFoundException If the provided directory does not
113
         * exist or is not a directory
114
         */
115
        public void setThemesDir(File themesDir) throws FileNotFoundException {
116
                if (!themesDir.exists() || !themesDir.isDirectory())
117
                        throw new FileNotFoundException();
118
                this.themesDir = themesDir;
119
        }
120

    
121
        /**
122
         * Gets the themes directory
123
         * @return
124
         */
125
        public File getThemesDir() {
126
                return themesDir;
127
        }
128

    
129
        /**
130
         *
131
         * Save the provided theme as default in the configuration file.
132
         * This will not change the default theme for this session, it will
133
         * just write the new selection in the configuration file (for
134
         * the next session).
135
         *
136
         * @param info The theme to be set as default for next session.
137
         */
138
        private void saveConfig(AbstractIconTheme info) {
139
                if (getThemesDir()==null || info==null || info.getResource()==null)
140
                        return;
141
                com.iver.andami.config.generate.AndamiOptions options = Launcher.getAndamiConfig().getAndamiOptions();
142
                if (options==null) {
143
                        options = new com.iver.andami.config.generate.AndamiOptions();
144
                        Launcher.getAndamiConfig().setAndamiOptions(options);
145
                }
146
                com.iver.andami.config.generate.IconTheme themeConfig = options.getIconTheme();
147
                if (themeConfig==null) {
148
                        themeConfig = new com.iver.andami.config.generate.IconTheme();
149
                        options.setIconTheme(themeConfig);
150
                }
151
                themeConfig.setBasedir(getThemesDir().getPath());
152
                themeConfig.setName(info.getName());
153
                themeConfig.setDescription(info.getDescription());
154
                themeConfig.setVersion(info.getVersion());
155
                if (info.getResource()!=null) {
156
                        if (info.getResource() instanceof File) {
157
                                File resource = (File) info.getResource();
158
                                themeConfig.setResource(resource.getName());
159
                        }
160
                        else if (info.getResource() instanceof ZipFile) {
161
                                ZipFile resource = (ZipFile) info.getResource();
162
                                themeConfig.setResource(resource.getName());
163
                        }
164
                }
165
        }
166

    
167
        /**
168
         * Gets the Icon theme stored in the configuration
169
         * @return AbstractIconTheme
170
         */
171
        public AbstractIconTheme readConfig() {
172
                if (Launcher.getAndamiConfig().getAndamiOptions()==null
173
                                || Launcher.getAndamiConfig().getAndamiOptions().getIconTheme()==null
174
                                || Launcher.getAndamiConfig().getAndamiOptions().getIconTheme().getResource()==null)
175
                        return null;
176

    
177
                com.iver.andami.config.generate.IconTheme selectedTheme = Launcher.getAndamiConfig().getAndamiOptions().getIconTheme();
178

    
179
                try {
180
                        setThemesDir(new File(selectedTheme.getBasedir()));
181
                        File themeFile = new File(selectedTheme.getBasedir()+File.separator+selectedTheme.getResource());
182
                        if (themeFile.exists()) {
183
                                AbstractIconTheme info;
184
                                try {
185
                                        // try to load a ZIPPED theme
186
                                        ZipFile zipfile = new ZipFile(selectedTheme.getResource());
187
                                        info = readInfoFromZip(zipfile);
188
                                        return info;
189
                                } catch (ZipException e) {
190
                                        // ZIPPED theme failed, try to load from directory
191
                                        if (themeFile.isFile() && themeFile.canRead()) {
192
                                                info = readInfoFromDir(new File(selectedTheme.getResource()));
193
                                                return info;
194
                                        }
195
                                } catch (IOException e) {}
196
                        }
197
                } catch (FileNotFoundException e1) {}
198
                return null;
199
        }
200

    
201
        /**
202
         * Gets the base name of a entry
203
         * @param fullname
204
         * @return
205
         */
206
        private String basename(String fullname) {
207
                String[] parts = fullname.split(File.separator+"|/");
208
                return parts[parts.length-1];
209
        }
210

    
211
        /**
212
         * Returns an icon theme from a file that receives like a parameter
213
         * @param zipFile
214
         * @return
215
         * @throws ZipException
216
         * @throws IOException
217
         */
218
        private IconThemeZip readInfoFromZip(File zipFile) throws ZipException, IOException {
219
                return readInfoFromZip(new ZipFile(zipFile));
220
        }
221

    
222
        /**
223
         * Returns an icon theme from a zip file that receives like a parameter
224
         * @param zipFile
225
         * @return IconThemeZip
226
         * @throws IOException
227
         */
228
        private IconThemeZip readInfoFromZip(ZipFile zipFile) throws IOException {
229
                IconThemeZip themeInfo;
230
                Enumeration entries = zipFile.entries();
231
                ZipEntry xmlEntry=null, dirEntry=null;
232
                // search for theme.xml and the directory names
233
                while (entries.hasMoreElements() && (xmlEntry==null||dirEntry==null)) {
234
                        ZipEntry entry = (ZipEntry) entries.nextElement();
235
                        if (entry.isDirectory()) {
236
                                dirEntry = entry;
237
                        }
238
                        if (basename(entry.getName()).equals(themeDefinitionFile)) {
239
                                xmlEntry = entry;
240
                        }
241
                }
242

    
243
                try {
244
                        // try with the XML file
245
                        if (xmlEntry!=null) {
246
                                themeInfo = readXML(zipFile.getInputStream(xmlEntry));
247
                                if (themeInfo.getDescription()==null)
248
                                        themeInfo.setDescription(zipFile.getName());
249
                                if (themeInfo.getName()==null)
250
                                        themeInfo.setName(themeInfo.getDescription());
251
                                themeInfo.setResource(zipFile);
252
                                return themeInfo;
253
                        }
254
                } catch (XmlPullParserException e) {
255
                        PluginServices.getLogger().error("Error loading theme "+zipFile.getName()+". ", e);
256
                }
257

    
258
                themeInfo = new IconThemeZip(def);
259
                themeInfo.setResource(zipFile);
260
                // now try with the directory
261
                if (dirEntry!=null) {
262
                        themeInfo.setName(dirEntry.getName());
263
                        themeInfo.setDescription(dirEntry.getName());
264
                        return themeInfo;
265
                }
266
                else { // otherwise just use the zipName
267
                        themeInfo.setName(zipFile.getName());
268
                        themeInfo.setDescription(zipFile.getName());
269
                        return themeInfo;
270
                }
271
        }
272

    
273
        /**
274
         * Read the properties of IconThemeZip from a XML
275
         * @param xmlStream
276
         * @return IconThemeZip
277
         * @throws XmlPullParserException
278
         * @throws IOException
279
         */
280
        private IconThemeZip readXML(InputStream xmlStream) throws XmlPullParserException, IOException {
281
                KXmlParser parser = new KXmlParser();
282
                // we use null encoding, in this way kxml2 tries to detect the encoding
283
                parser.setInput(xmlStream, null);
284
                IconThemeZip themeInfo=new IconThemeZip(def);
285
                for (parser.next(); parser.getEventType()!=KXmlParser.END_DOCUMENT; parser.next()) {
286
                        // este bucle externo recorre las etiquetas de primer y segundo nivel
287
                        if (parser.getEventType()==KXmlParser.START_TAG) {
288
                                if (parser.getName().equals("name")) {
289
                                        themeInfo.setName(parser.nextText());
290
                                }
291
                                else if (parser.getName().equals("description")) {
292
                                        themeInfo.setDescription(parser.nextText());
293
                                }
294
                                else if (parser.getName().equals("version")) {
295
                                        themeInfo.setVersion(parser.nextText());
296
                                }
297
                        }
298
                }
299
                return themeInfo;
300
        }
301

    
302
        /**
303
         * Returns a IconThemeDir from a directory
304
         * @param dir
305
         * @return
306
         */
307
        private IconThemeDir readInfoFromDir(File dir){
308
                File themeDefinition = new File(dir + File.separator + themeDefinitionFile);
309
                IconThemeDir themeInfo;
310
                try {
311
                        // try reading the XML file
312
                        if (themeDefinition.exists() && themeDefinition.isFile()) {
313
                                themeInfo = readXMLDir(new FileInputStream(themeDefinition));
314
                                if (themeInfo.getDescription()==null)
315
                                        themeInfo.setDescription(dir.getName());
316
                                if (themeInfo.getName()==null)
317
                                        themeInfo.setName(themeInfo.getDescription());
318
                                themeInfo.setResource(dir);
319
                                return themeInfo;
320
                        }
321
                } catch (IOException e) {}
322
                catch (XmlPullParserException e) {
323
                        e.printStackTrace();
324
                }
325
                // the XML parsing failed, just show the dir name
326
                themeInfo = new IconThemeDir(def);
327
                themeInfo.setName(dir.getName());
328
                themeInfo.setDescription(dir.getName());
329
                themeInfo.setResource(dir);
330
                return themeInfo;
331
        }
332

    
333
        /**
334
         * Read the properties of IconThemeDir from a XML
335
         * @param xmlStream
336
         * @return
337
         * @throws XmlPullParserException
338
         * @throws IOException
339
         */
340
        private IconThemeDir readXMLDir(InputStream xmlStream) throws XmlPullParserException, IOException {
341
                KXmlParser parser = new KXmlParser();
342
                // we use null encoding, in this way kxml2 tries to detect the encoding
343
                parser.setInput(xmlStream, null);
344
                IconThemeDir themeInfo=new IconThemeDir(def);
345
                for (parser.next(); parser.getEventType()!=KXmlParser.END_DOCUMENT; parser.next()) {
346
                        // este bucle externo recorre las etiquetas de primer y segundo nivel
347
                        if (parser.getEventType()==KXmlParser.START_TAG) {
348
                                if (parser.getName().equals("name")) {
349
                                        themeInfo.setName(parser.nextText());
350
                                }
351
                                else if (parser.getName().equals("description")) {
352
                                        themeInfo.setDescription(parser.nextText());
353
                                }
354
                                else if (parser.getName().equals("version")) {
355
                                        themeInfo.setVersion(parser.nextText());
356
                                }
357
                        }
358
                }
359
                return themeInfo;
360
        }
361

    
362
        /*
363
         *  (non-Javadoc)
364
         * @see java.util.Collection#size()
365
         */
366
        public int size() {
367
                return themes.size();
368
        }
369
        /*
370
         *  (non-Javadoc)
371
         * @see java.util.Collection#isEmpty()
372
         */
373
        public boolean isEmpty() {
374
                if (themes.size()==0)return true;
375
                else return false;
376
        }
377

    
378
        /*
379
         *  (non-Javadoc)
380
         * @see java.util.Collection#contains(java.lang.Object)
381
         */
382
        public boolean contains(Object o) {
383
                return themes.contains(o);
384
        }
385

    
386
        /*
387
         *  (non-Javadoc)
388
         * @see java.lang.Iterable#iterator()
389
         */
390
        public Iterator iterator() {
391
                return themes.iterator();
392
        }
393

    
394
        /*
395
         *  (non-Javadoc)
396
         * @see java.util.Collection#toArray()
397
         */
398
        public Object[] toArray() {
399
                return themes.toArray();
400
        }
401

    
402
        /*
403
         *  (non-Javadoc)
404
         * @see java.util.Collection#toArray(Object[] a)
405
         */
406
        public Object[] toArray(Object[] a) {
407
                return themes.toArray(a);
408
        }
409

    
410
        /*
411
         *  (non-Javadoc)
412
         * @see java.util.Collection#remove(java.lang.Object)
413
         */
414
        public boolean add(Object o) {
415
                return themes.add((AbstractIconTheme) o);
416
        }
417

    
418
        /*
419
         *  (non-Javadoc)
420
         * @see java.util.Collection#remove(java.lang.Object)
421
         */
422
        public boolean remove(Object o) {
423
                return themes.remove(o);
424
        }
425

    
426
        /*
427
         *  (non-Javadoc)
428
         * @see java.util.Collection#containsAll(Collection)
429
         */
430
        public boolean containsAll(Collection c) {
431
                return themes.containsAll(c);
432
        }
433

    
434
        /*
435
         *  (non-Javadoc)
436
         * @see java.util.Collection#addAll(Collection)
437
         */
438
        public boolean addAll(Collection c) {
439
                return themes.addAll(c);
440
        }
441

    
442
        /*
443
         *  (non-Javadoc)
444
         * @see java.util.Collection#removeAll(Collection)
445
         */
446
        public boolean removeAll(Collection c) {
447
                return themes.removeAll(c);
448
        }
449

    
450
        /*
451
         *  (non-Javadoc)
452
         * @see java.util.Collection#retainAll(Collection)
453
         */
454
        public boolean retainAll(Collection c) {
455
                return themes.retainAll(c);
456
        }
457

    
458
        /*
459
         *  (non-Javadoc)
460
         * @see java.util.Collection#clear()
461
         */
462
        public void clear() {
463
                themes.clear();
464
        }
465

    
466
}