KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > roller > business > ThemeManagerImpl


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. The ASF licenses this file to You
4  * under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License. For additional information regarding
15  * copyright in this work, please see the NOTICE file in the top level
16  * directory of this distribution.
17  */

18
19 package org.apache.roller.business;
20
21 import java.io.File JavaDoc;
22 import java.io.FileInputStream JavaDoc;
23 import java.io.FileNotFoundException JavaDoc;
24 import java.io.FileReader JavaDoc;
25 import java.io.FilenameFilter JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.InputStreamReader JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Collection JavaDoc;
30 import java.util.Collections JavaDoc;
31 import java.util.Date JavaDoc;
32 import java.util.HashMap JavaDoc;
33 import java.util.Iterator JavaDoc;
34 import java.util.List JavaDoc;
35 import java.util.Map JavaDoc;
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38 import org.apache.roller.RollerException;
39 import org.apache.roller.ThemeNotFoundException;
40 import org.apache.roller.config.RollerConfig;
41 import org.apache.roller.model.RollerFactory;
42 import org.apache.roller.model.ThemeManager;
43 import org.apache.roller.model.UserManager;
44 import org.apache.roller.pojos.Theme;
45 import org.apache.roller.pojos.ThemeTemplate;
46 import org.apache.roller.pojos.WeblogTemplate;
47 import org.apache.roller.pojos.WebsiteData;
48
49
50 /**
51  * Base implementation of a ThemeManager.
52  *
53  * This particular implementation reads theme data off the filesystem
54  * and assumes that those themes are not changable at runtime.
55  */

56 public class ThemeManagerImpl implements ThemeManager {
57     
58     private static Log log = LogFactory.getLog(ThemeManagerImpl.class);
59     
60     private Map JavaDoc themes = null;
61     
62     
63     protected ThemeManagerImpl() {
64         
65         // rather than be lazy we are going to load all themes from
66
// the disk preemptively during initialization and cache them
67
log.debug("Initializing ThemeManagerImpl");
68         
69         this.themes = this.loadAllThemesFromDisk();
70         log.info("Loaded "+this.themes.size()+" themes from disk.");
71     }
72     
73     
74     /**
75      * @see org.apache.roller.model.ThemeManager#getTheme(java.lang.String)
76      */

77     public Theme getTheme(String JavaDoc name)
78         throws ThemeNotFoundException, RollerException {
79         
80         Theme theme = (Theme) this.themes.get(name);
81         if(theme == null)
82             throw new ThemeNotFoundException("Couldn't find theme ["+name+"]");
83         
84         return theme;
85     }
86     
87     
88     /**
89      * @see org.apache.roller.model.ThemeManager#getThemeById(java.lang.String)
90      */

91     public Theme getThemeById(String JavaDoc id)
92         throws ThemeNotFoundException, RollerException {
93         
94         // In this implementation where themes come from the filesystem we
95
// know that the name and id for a theme are the same
96
return this.getTheme(id);
97     }
98     
99     
100     /**
101      * @see org.apache.roller.model.ThemeManager#getThemesList()
102      */

103     public List JavaDoc getThemesList() {
104         
105         List JavaDoc themes = new ArrayList JavaDoc(this.themes.keySet());
106         
107         // sort 'em ... the natural sorting order for Strings is alphabetical
108
Collections.sort(themes);
109         
110         return themes;
111     }
112     
113     
114     /**
115      * @see org.apache.roller.model.ThemeManager#getEnabledThemesList()
116      */

117     public List JavaDoc getEnabledThemesList() {
118         
119         Collection JavaDoc all_themes = this.themes.values();
120         
121         // make a new list of only the enabled themes
122
List JavaDoc enabled_themes = new ArrayList JavaDoc();
123         Iterator JavaDoc it = all_themes.iterator();
124         Theme theme = null;
125         while(it.hasNext()) {
126             theme = (Theme) it.next();
127             if(theme.isEnabled())
128                 enabled_themes.add(theme.getName());
129         }
130                 
131         // sort 'em ... the natural sorting order for Strings is alphabetical
132
Collections.sort(enabled_themes);
133         
134         return enabled_themes;
135     }
136     
137     
138     /**
139      * @see org.apache.roller.model.ThemeManager#getTemplate(String, String)
140      */

141     public ThemeTemplate getTemplate(String JavaDoc theme_name, String JavaDoc template_name)
142         throws ThemeNotFoundException, RollerException {
143         
144         // basically we just try and lookup the theme first, then template
145
Theme theme = this.getTheme(theme_name);
146         
147         return theme.getTemplate(template_name);
148     }
149     
150     
151     /**
152      * @see org.apache.roller.model.ThemeManager#getTemplateById(java.lang.String)
153      */

154     public ThemeTemplate getTemplateById(String JavaDoc id)
155         throws ThemeNotFoundException, RollerException {
156         
157         if(id == null)
158             throw new ThemeNotFoundException("Theme id was null");
159         
160         // in our case we expect a template id to be <theme>:<template>
161
// so extract each piece and do the lookup
162
String JavaDoc[] split = id.split(":", 2);
163         if(split.length != 2)
164             throw new ThemeNotFoundException("Invalid theme id ["+id+"]");
165         
166         return this.getTemplate(split[0], split[1]);
167     }
168     
169     
170     /**
171      * @see org.apache.roller.model.ThemeManager#getTemplateByLink(java.lang.String)
172      */

173     public ThemeTemplate getTemplateByLink(String JavaDoc theme_name, String JavaDoc template_link)
174         throws ThemeNotFoundException, RollerException {
175         
176         // basically we just try and lookup the theme first, then template
177
Theme theme = this.getTheme(theme_name);
178         
179         return theme.getTemplateByLink(template_link);
180     }
181     
182     
183     /**
184      * This is a convenience method which loads all the theme data from
185      * themes stored on the filesystem in the roller webapp /themes/ directory.
186      */

187     private Map JavaDoc loadAllThemesFromDisk() {
188         
189         Map JavaDoc themes = new HashMap JavaDoc();
190         
191         // NOTE: we need to figure out how to get the roller context path
192
String JavaDoc themespath = RollerConfig.getProperty("context.realPath");
193         if(themespath.endsWith(File.separator))
194             themespath += "themes";
195         else
196             themespath += File.separator + "themes";
197         
198         // first, get a list of the themes available
199
File JavaDoc themesdir = new File JavaDoc(themespath);
200         FilenameFilter JavaDoc filter = new FilenameFilter JavaDoc() {
201             public boolean accept(File JavaDoc dir, String JavaDoc name) {
202                 File JavaDoc file =
203                         new File JavaDoc(dir.getAbsolutePath() + File.separator + name);
204                 return file.isDirectory();
205             }
206         };
207         String JavaDoc[] themenames = themesdir.list(filter);
208         
209         if(themenames == null)
210             themenames = new String JavaDoc[0];
211         
212         // now go through each theme and read all it's templates
213
Theme theme = null;
214         for(int i=0; i < themenames.length; i++) {
215             try {
216                 theme = this.loadThemeFromDisk(themenames[i],
217                             themespath + File.separator + themenames[i]);
218                 themes.put(theme.getName(), theme);
219             } catch (Throwable JavaDoc unexpected) {
220                 // shouldn't happen, so let's learn why it did
221
log.error("Problem reading theme " + themenames[i], unexpected);
222             }
223         }
224         
225         return themes;
226     }
227         
228     /**
229      * Another convenience method which knows how to load a single theme
230      * off the filesystem and return a Theme object
231      */

232     private Theme loadThemeFromDisk(String JavaDoc theme_name, String JavaDoc themepath) {
233         
234         log.info("Loading theme "+theme_name);
235         
236         Theme theme = new Theme();
237         theme.setName(theme_name);
238         theme.setAuthor("Roller");
239         theme.setLastEditor("Roller");
240         theme.setEnabled(true);
241         
242         // start by getting a list of the .vm files for this theme
243
File JavaDoc themedir = new File JavaDoc(themepath);
244         FilenameFilter JavaDoc filter = new FilenameFilter JavaDoc()
245         {
246             public boolean accept(File JavaDoc dir, String JavaDoc name)
247             {
248                 return name.endsWith(".vm");
249             }
250         };
251         String JavaDoc[] templates = themedir.list(filter);
252         
253         // go through each .vm file and read in its contents to a ThemeTemplate
254
String JavaDoc template_name = null;
255         ThemeTemplate theme_template = null;
256         for (int i=0; i < templates.length; i++) {
257             // strip off the .vm part
258
template_name = templates[i].substring(0, templates[i].length() - 3);
259             File JavaDoc template_file = new File JavaDoc(themepath + File.separator + templates[i]);
260             
261             // Continue reading theme even if problem encountered with one file
262
String JavaDoc msg = "read theme template file ["+template_file+"]";
263             if(!template_file.exists() && !template_file.canRead()) {
264                 log.error("Couldn't " + msg);
265                 continue;
266             }
267             char[] chars = null;
268             int length;
269             try {
270 // FileReader reader = new FileReader(template_file);
271
chars = new char[(int) template_file.length()];
272                 FileInputStream JavaDoc stream = new FileInputStream JavaDoc(template_file);
273                 InputStreamReader JavaDoc reader = new InputStreamReader JavaDoc(stream, "UTF-8");
274                 length = reader.read(chars);
275             } catch (Exception JavaDoc noprob) {
276                 log.error("Exception while attempting to " + msg);
277                 if (log.isDebugEnabled()) log.debug(noprob);
278                 continue;
279             }
280             
281             // Strip "_" from name to form link
282
boolean navbar = true;
283             String JavaDoc template_link = template_name;
284             if (template_name.startsWith("_") && template_name.length() > 1) {
285                 navbar = false;
286                 template_link = template_link.substring(1);
287                 log.debug("--- " + template_link);
288             }
289             
290             String JavaDoc decorator = "_decorator";
291             if("_decorator".equals(template_name)) {
292                 decorator = null;
293             }
294             
295             // construct ThemeTemplate representing this file
296
// a few restrictions for now:
297
// - we only allow "velocity" for the template language
298
// - decorator is always "_decorator" or null
299
// - all theme templates are considered not hidden
300
theme_template = new ThemeTemplate(
301                     theme,
302                     theme_name+":"+template_name,
303                     template_name,
304                     template_name,
305                     new String JavaDoc(chars, 0, length),
306                     template_link,
307                     new Date JavaDoc(template_file.lastModified()),
308                     "velocity",
309                     false,
310                     navbar,
311                     decorator);
312
313             // add it to the theme
314
theme.setTemplate(template_name, theme_template);
315         }
316         
317         // use the last mod date of the last template file
318
// as the last mod date of the theme
319
theme.setLastModified(theme_template.getLastModified());
320         
321         return theme;
322     }
323
324     /**
325      * Helper method that copies down the pages from a given theme into a
326      * users weblog templates.
327      *
328      * @param rreq Request wrapper.
329      * @param theme Name of theme to save.
330      * @throws RollerException
331      */

332     public void saveThemePages(WebsiteData website, Theme theme)
333         throws RollerException {
334         
335         log.debug("Setting custom templates for website: "+website.getName());
336         
337         try {
338             UserManager userMgr = RollerFactory.getRoller().getUserManager();
339             
340             Collection JavaDoc templates = theme.getTemplates();
341             Iterator JavaDoc iter = templates.iterator();
342             ThemeTemplate theme_template = null;
343             while ( iter.hasNext() ) {
344                 theme_template = (ThemeTemplate) iter.next();
345                 
346                 WeblogTemplate template = null;
347                 
348                 if(theme_template.getName().equals(WeblogTemplate.DEFAULT_PAGE)) {
349                     // this is the main Weblog template
350
try {
351                         template = userMgr.getPage(website.getDefaultPageId());
352                     } catch(Exception JavaDoc e) {
353                         // user may not have a default page yet
354
}
355                 } else {
356                     // any other template
357
template = userMgr.getPageByName(website, theme_template.getName());
358                 }
359                 
360                 
361                 if (template != null) {
362                     // User already has page by that name, so overwrite it.
363
template.setContents(theme_template.getContents());
364                     template.setLink(theme_template.getLink());
365                     
366                 } else {
367                     // User does not have page by that name, so create new page.
368
template = new WeblogTemplate(
369                             null, // id
370
website, // website
371
theme_template.getName(), // name
372
theme_template.getDescription(), // description
373
theme_template.getLink(), // link
374
theme_template.getContents(), // contents
375
new Date JavaDoc(), // last mod
376
theme_template.getTemplateLanguage(), // temp lang
377
theme_template.isHidden(), // hidden
378
theme_template.isNavbar(), // navbar
379
theme_template.getDecoratorName() // decorator
380
);
381                     userMgr.savePage( template );
382                 }
383             }
384             
385             // now update this website's theme to custom
386
website.setEditorTheme(Theme.CUSTOM);
387             
388             // if this is the first time someone is customizing a theme then
389
// we need to set a default page
390
if(website.getDefaultPageId() == null ||
391                     website.getDefaultPageId().trim().equals("") ||
392                     website.getDefaultPageId().equals("dummy")) {
393                 // we have to go back to the db to figure out the id
394
WeblogTemplate template = userMgr.getPageByName(website, "Weblog");
395                 if(template != null) {
396                     log.debug("Setting default page to "+template.getId());
397                     website.setDefaultPageId(template.getId());
398                 }
399             }
400             
401             // we also want to set the weblogdayid
402
WeblogTemplate dayTemplate = userMgr.getPageByName(website, "_day");
403             if(dayTemplate != null) {
404                 log.debug("Setting default day page to "+dayTemplate.getId());
405                 website.setWeblogDayPageId(dayTemplate.getId());
406             }
407             
408             // save our updated website
409
userMgr.saveWebsite(website);
410             
411         } catch (Exception JavaDoc e) {
412             log.error("ERROR in action",e);
413             throw new RollerException( e );
414         }
415     }
416 }
417
Popular Tags