File Source: ThemeManagerImpl.java

         /* 
    P/P   *  Method: org.apache.roller.weblogger.business.themes.ThemeManagerImpl$1__static_init
          */
     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.weblogger.business.themes;
    20  
    21  import java.io.File;
    22  import java.io.FilenameFilter;
    23  import java.util.ArrayList;
    24  import java.util.Collections;
    25  import java.util.Date;
    26  import java.util.HashMap;
    27  import java.util.HashSet;
    28  import java.util.Iterator;
    29  import java.util.List;
    30  import java.util.Map;
    31  import java.util.Set;
    32  import org.apache.commons.logging.Log;
    33  import org.apache.commons.logging.LogFactory;
    34  import org.apache.roller.weblogger.WebloggerException;
    35  import org.apache.roller.weblogger.business.FileManager;
    36  import org.apache.roller.weblogger.business.InitializationException;
    37  import org.apache.roller.weblogger.business.Weblogger;
    38  import org.apache.roller.weblogger.business.UserManager;
    39  import org.apache.roller.weblogger.config.WebloggerConfig;
    40  import org.apache.roller.weblogger.pojos.Theme;
    41  import org.apache.roller.weblogger.pojos.ThemeResource;
    42  import org.apache.roller.weblogger.pojos.ThemeTemplate;
    43  import org.apache.roller.weblogger.pojos.WeblogTemplate;
    44  import org.apache.roller.weblogger.pojos.WeblogTheme;
    45  import org.apache.roller.weblogger.pojos.Weblog;
    46  
    47  
    48  /**
    49   * Base implementation of a ThemeManager.
    50   * 
    51   * This particular implementation reads theme data off the filesystem 
    52   * and assumes that those themes are not changable at runtime.
    53   */
    54  @com.google.inject.Singleton
    55  public class ThemeManagerImpl implements ThemeManager {
    56      
             /* 
    P/P       *  Method: org.apache.roller.weblogger.business.themes.ThemeManagerImpl__static_init
              * 
              *  Postconditions:
              *    init'ed(log)
              */
    57      private static Log log = LogFactory.getLog(ThemeManagerImpl.class);
    58      
    59      private final Weblogger roller;
    60      
    61      // directory where themes are kept
    62      private String themeDir = null;
    63      
    64      // the Map contains ... (theme id, Theme)
    65      private Map themes = null;
    66      
    67      
    68      @com.google.inject.Inject
             /* 
    P/P       *  Method: void org.apache.roller.weblogger.business.themes.ThemeManagerImpl(Weblogger)
              * 
              *  Preconditions:
              *    org/apache/roller/weblogger/config/WebloggerConfig.config != null
              *    org/apache/roller/weblogger/config/WebloggerConfig.log != null
              * 
              *  Presumptions:
              *    java.io.File:canRead(...)@85 == 1
              *    java.io.File:exists(...)@85 == 1
              *    java.io.File:isDirectory(...)@85 == 1
              *    java.lang.String:length(...)@75 >= 1
              * 
              *  Postconditions:
              *    java.lang.String:substring(...)._tainted == 0
              *    this.roller == roller
              *    init'ed(this.roller)
              *    this.themeDir != null
              *    this.themes == null
              * 
              *  Test Vectors:
              *    java.lang.String:endsWith(...)@79: {0}, {1}
              */
    69      protected ThemeManagerImpl(Weblogger roller) {
    70          
    71          this.roller = roller;
    72          
    73          // get theme directory from config and verify it
    74          this.themeDir = WebloggerConfig.getProperty("themes.dir");
+   75          if(themeDir == null || themeDir.trim().length() < 1) {
    76              throw new RuntimeException("couldn't get themes directory from config");
    77          } else {
    78              // chop off trailing slash if it exists
    79              if(themeDir.endsWith("/")) {
    80                  themeDir = themeDir.substring(0, themeDir.length()-1);
    81              }
    82              
    83              // make sure it exists and is readable
    84              File themeDirFile = new File(themeDir);
    85              if(!themeDirFile.exists() || 
    86                      !themeDirFile.isDirectory() || 
    87                      !themeDirFile.canRead()) {
    88                  throw new RuntimeException("couldn't access theme dir ["+themeDir+"]");
    89              }
    90          }
    91      }
    92      
    93      
    94      public void initialize() throws InitializationException {
    95          
                 /* 
    P/P           *  Method: void initialize()
                  * 
                  *  Preconditions:
                  *    log != null
                  *    init'ed(this.themeDir)
                  *    (soft) org/apache/roller/weblogger/business/themes/SharedThemeFromDir.log != null
                  * 
                  *  Postconditions:
                  *    this.themes == One-of{old this.themes, &new HashMap(loadAllThemesFromDisk#1)}
                  *    new HashMap(loadAllThemesFromDisk#1) num objects <= 1
                  * 
                  *  Test Vectors:
                  *    this.themeDir: Addr_Set{null}, Inverse{null}
                  */
    96          log.debug("Initializing Theme Manager");
    97          
    98          if(themeDir != null) {
    99              // rather than be lazy we are going to load all themes from
   100              // the disk preemptively and cache them
   101              this.themes = loadAllThemesFromDisk();
   102              
   103              log.info("Loaded "+this.themes.size()+" themes from disk.");
   104          }
   105      }
   106      
   107      
   108      /**
   109       * @see org.apache.roller.weblogger.model.ThemeManager#getTheme(java.lang.String)
   110       */
   111      public SharedTheme getTheme(String id) 
   112              throws ThemeNotFoundException, WebloggerException {
   113          
   114          // try to lookup theme from library
                 /* 
    P/P           *  Method: SharedTheme getTheme(String)
                  * 
                  *  Preconditions:
                  *    this.themes != null
                  * 
                  *  Presumptions:
                  *    java.util.Map:get(...)@115 != null
                  * 
                  *  Postconditions:
                  *    (soft) return_value != null
                  */
   115          SharedTheme theme = (SharedTheme) this.themes.get(id);
   116          
   117          // no theme?  throw exception.
   118          if(theme == null) {
   119              throw new ThemeNotFoundException("Couldn't find theme ["+id+"]");
   120          }
   121          
   122          return theme;
   123      }
   124      
   125      
   126      /**
   127       * @see org.apache.roller.weblogger.model.ThemeManager#getTheme(weblog)
   128       */
   129      public WeblogTheme getTheme(Weblog weblog) throws WebloggerException {
   130          
                 /* 
    P/P           *  Method: WeblogTheme getTheme(Weblog)
                  * 
                  *  Preconditions:
                  *    (soft) log != null
                  *    (soft) this.roller != null
                  *    (soft) this.themes != null
                  * 
                  *  Postconditions:
                  *    return_value in Addr_Set{null,&new WeblogSharedTheme(getTheme#2),&new WeblogCustomTheme(getTheme#1)}
                  *    new WeblogCustomTheme(getTheme#1) num objects <= 1
                  *    new WeblogSharedTheme(getTheme#2) num objects <= 1
                  *    new WeblogSharedTheme(getTheme#2).theme != null
                  * 
                  *  Test Vectors:
                  *    weblog: Inverse{null}, Addr_Set{null}
                  *    java.lang.String:equals(...)@137: {0}, {1}
                  *    java.util.Map:get(...)@144: Addr_Set{null}, Inverse{null}
                  *    org.apache.roller.weblogger.pojos.Weblog:getEditorTheme(...)@137: Addr_Set{null}, Inverse{null}
                  */
   131          if(weblog == null)
   132              return null;
   133          
   134          WeblogTheme weblogTheme = null;
   135          
   136          // if theme is custom or null then return a WeblogCustomTheme
   137          if(weblog.getEditorTheme() == null || 
   138                  WeblogTheme.CUSTOM.equals(weblog.getEditorTheme())) {
   139              weblogTheme = new WeblogCustomTheme(weblog);
   140              
   141          // otherwise we are returning a WeblogSharedTheme
   142          } else {
+  143              ThemeManager themeMgr = roller.getThemeManager();
   144              SharedTheme staticTheme =
   145                      (SharedTheme) this.themes.get(weblog.getEditorTheme());
   146              if(staticTheme != null) {
   147                  weblogTheme = new WeblogSharedTheme(weblog, staticTheme);
   148              } else {
   149                  log.warn("Unable to lookup theme "+weblog.getEditorTheme());
   150              }
   151          }
   152          
   153          // TODO: if somehow the theme is still null should we provide some
   154          // kind of fallback option like a default theme?
   155          
   156          return weblogTheme;
   157      }
   158  
   159      
   160      /**
   161       * @see org.apache.roller.weblogger.model.ThemeManager#getEnabledThemesList()
   162       *
   163       * TODO: reimplement enabled vs. disabled logic once we support it
   164       */
   165      public List getEnabledThemesList() {
   166          
                 /* 
    P/P           *  Method: List getEnabledThemesList()
                  * 
                  *  Preconditions:
                  *    this.themes != null
                  * 
                  *  Postconditions:
                  *    return_value == &new ArrayList(getEnabledThemesList#1)
                  *    new ArrayList(getEnabledThemesList#1) num objects == 1
                  */
   167          List all_themes = new ArrayList(this.themes.values());
   168                  
   169          // sort 'em ... default ordering for themes is by name
   170          Collections.sort(all_themes);
   171          
   172          return all_themes;
   173      }
   174      
   175      
   176      /**
   177       * @see org.apache.roller.weblogger.model.ThemeManager#importTheme(website, theme)
   178       */
   179      public void importTheme(Weblog website, SharedTheme theme)
   180              throws WebloggerException {
   181          
                 /* 
    P/P           *  Method: void importTheme(Weblog, SharedTheme)
                  * 
                  *  Preconditions:
                  *    log != null
                  *    theme != null
                  *    init'ed(theme.name)
                  *    theme.resources != null
                  *    this.roller != null
                  *    this.roller.userManager != null
                  *    this.roller.userManager.strategy != null
                  *    this.roller.userManager.strategy.threadLocalEntityManager != null
                  *    website != null
                  *    (soft) org/apache/roller/weblogger/business/FileManagerImpl.log != null
                  *    ...
                  * 
                  *  Presumptions:
                  *    java.util.Iterator:next(...)@192 != null
                  *    java.util.Iterator:next(...)@272 != null
                  *    getUserManager(...)@185...strategy != userMgr.roller.userManager.strategy
                  *    org.apache.roller.weblogger.business.themes.SharedTheme:getStylesheet(...)@260 != null
                  *    org.apache.roller.weblogger.business.themes.SharedTheme:getTemplates(...)@190 != null
                  *    ...
                  * 
                  *  Test Vectors:
                  *    java.lang.Object:equals(...)@223: {1}, {0}
                  *    java.lang.String:equals(...)@197: {1}, {0}
                  *    java.util.Iterator:hasNext(...)@191: {0}, {1}
                  *    java.util.Iterator:hasNext(...)@271: {0}, {1}
                  *    java.util.Set:contains(...)@247: {1}, {0}
                  *    org.apache.roller.weblogger.business.themes.SharedTheme:getStylesheet(...)@259: Addr_Set{null}, Inverse{null}
                  *    org.apache.roller.weblogger.pojos.ThemeResource:isDirectory(...)@277: {0}, {1}
                  *    org.apache.roller.weblogger.pojos.ThemeTemplate:getAction(...)@197: Addr_Set{null}, Inverse{null}
                  */
   182          log.debug("Importing theme ["+theme.getName()+"] to weblog ["+website.getName()+"]");
   183          
   184          try {
   185              UserManager userMgr = roller.getUserManager();
   186              
   187              Set importedActionTemplates = new HashSet();
   188              ThemeTemplate themeTemplate = null;
   189              ThemeTemplate stylesheetTemplate = theme.getStylesheet();
   190              Iterator iter = theme.getTemplates().iterator();
   191              while ( iter.hasNext() ) {
   192                  themeTemplate = (ThemeTemplate) iter.next();
   193                  
   194                  WeblogTemplate template = null;
   195                  
   196                  // if template is an action, lookup by action
   197                  if(themeTemplate.getAction() != null &&
   198                          !themeTemplate.getAction().equals(WeblogTemplate.ACTION_CUSTOM)) {
   199                      template = userMgr.getPageByAction(website, themeTemplate.getAction());
   200                      if(template != null) {
   201                          importedActionTemplates.add(themeTemplate.getAction());
   202                      }
   203                      
   204                  // otherwise, lookup by name
   205                  } else {
   206                      template = userMgr.getPageByName(website, themeTemplate.getName());
   207                  }
   208                  
   209                  // Weblog does not have this template, so create it.
   210                  boolean newTmpl = false;
   211                  if (template == null) {
   212                      template = new WeblogTemplate();
   213                      template.setWebsite(website);
   214                      newTmpl = true;
   215                  }
   216  
   217                  // TODO: fix conflict situation
   218                  // it's possible that someone has defined a theme template which
   219                  // matches 2 existing templates, 1 by action, the other by name
   220                  
   221                  // update template attributes
   222                  // NOTE: we don't want to copy the template data for an existing stylesheet
   223                  if(newTmpl || !themeTemplate.equals(stylesheetTemplate)) {
   224                      template.setAction(themeTemplate.getAction());
   225                      template.setName(themeTemplate.getName());
   226                      template.setDescription(themeTemplate.getDescription());
   227                      template.setLink(themeTemplate.getLink());
   228                      template.setContents(themeTemplate.getContents());
   229                      template.setHidden(themeTemplate.isHidden());
   230                      template.setNavbar(themeTemplate.isNavbar());
   231                      template.setTemplateLanguage(themeTemplate.getTemplateLanguage());
   232                      // NOTE: decorators are deprecated starting in 4.0
   233                      template.setDecoratorName(null);
   234                      template.setLastModified(new Date());
   235                      
   236                      // save it
   237                      userMgr.savePage( template );
   238                  }
   239              }
   240              
   241              // now, see if the weblog has left over action templates that
   242              // need to be deleted because they aren't in their new theme
   243              for(int i=0; i < WeblogTemplate.ACTIONS.length; i++) {
   244                  String action = WeblogTemplate.ACTIONS[i];
   245                  
   246                  // if we didn't import this action then see if it should be deleted
   247                  if(!importedActionTemplates.contains(action)) {
   248                      WeblogTemplate toDelete = userMgr.getPageByAction(website, action);
   249                      if(toDelete != null) {
   250                          log.debug("Removing stale action template "+toDelete.getId());
   251                          userMgr.removePage(toDelete);
   252                      }
   253                  }
   254              }
   255              
   256              
   257              // always update this weblog's theme and customStylesheet, then save
   258              website.setEditorTheme(WeblogTheme.CUSTOM);
   259              if(theme.getStylesheet() != null) {
   260                  website.setCustomStylesheetPath(theme.getStylesheet().getLink());
   261              }
   262              userMgr.saveWebsite(website);
   263              
   264              
   265              // now lets import all the theme resources
   266              FileManager fileMgr = roller.getFileManager();
   267              
   268              List resources = theme.getResources();
   269              Iterator iterat = resources.iterator();
   270              ThemeResource resource = null;
   271              while ( iterat.hasNext() ) {
   272                  resource = (ThemeResource) iterat.next();
   273                  
   274                  log.debug("Importing resource to "+resource.getPath());
   275                  
   276                  try {
   277                      if(resource.isDirectory()) {
   278                          fileMgr.createDirectory(website, resource.getPath());
   279                      } else {
   280                          // save file without file-type, quota checks, etc.
   281                          fileMgr.saveFile(website, resource.getPath(), "text/plain", 
   282                                  resource.getLength(), resource.getInputStream(), false);
   283                      }
   284                  } catch (Exception ex) {
   285                      log.info(ex);
   286                  }
   287              }
   288              
   289          } catch (Exception e) {
   290              log.error("ERROR importing theme", e);
   291              throw new WebloggerException( e );
   292          }
   293      }
   294      
   295      
   296      /**
   297       * This is a convenience method which loads all the theme data from
   298       * themes stored on the filesystem in the roller webapp /themes/ directory.
   299       */
   300      private Map loadAllThemesFromDisk() {
   301          
                 /* 
    P/P           *  Method: Map loadAllThemesFromDisk()
                  * 
                  *  Preconditions:
                  *    init'ed(this.themeDir)
                  *    (soft) log != null
                  *    (soft) org/apache/roller/weblogger/business/themes/SharedThemeFromDir.log != null
                  * 
                  *  Presumptions:
                  *    init'ed(java.io.File.separator)
                  *    themenames.length@313 <= 232-1
                  * 
                  *  Postconditions:
                  *    return_value == &new HashMap(loadAllThemesFromDisk#1)
                  *    new HashMap(loadAllThemesFromDisk#1) num objects == 1
                  * 
                  *  Test Vectors:
                  *    java.io.File:list(...)@313: Inverse{null}, Addr_Set{null}
                  */
   302          Map themes = new HashMap();
   303          
   304          // first, get a list of the themes available
   305          File themesdir = new File(this.themeDir);
                 /* 
    P/P           *  Method: void org.apache.roller.weblogger.business.themes.ThemeManagerImpl$1(ThemeManagerImpl)
                  */
   306          FilenameFilter filter = new FilenameFilter() {
   307              public boolean accept(File dir, String name) {
                         /* 
    P/P                   *  Method: bool accept(File, String)
                          * 
                          *  Preconditions:
                          *    dir != null
                          * 
                          *  Presumptions:
                          *    init'ed(java.io.File.separator)
                          * 
                          *  Postconditions:
                          *    init'ed(return_value)
                          */
   308                  File file =
   309                          new File(dir.getAbsolutePath() + File.separator + name);
   310                  return file.isDirectory();
   311              }
   312          };
   313          String[] themenames = themesdir.list(filter);
   314          
   315          if(themenames == null) {
   316              log.warn("No themes loaded!  Perhaps you specified the wrong "+
   317                      "location for your themes directory?");
   318          }
   319          
   320          // now go through each theme and load it into a Theme object
   321          for(int i=0; i < themenames.length; i++) {
   322              try {
   323                  Theme theme = new SharedThemeFromDir(this.themeDir + File.separator + themenames[i]);
+  324                  if(theme != null) {
   325                      themes.put(theme.getId(), theme);
   326                  }
   327              } catch (Throwable unexpected) {
   328                  // shouldn't happen, so let's learn why it did
   329                  log.error("Problem reading theme " + themenames[i], unexpected);
   330              }
   331          }
   332          
   333          return themes;
   334      }
   335      
   336  }








SofCheck Inspector Build Version : 2.18479
ThemeManagerImpl.java 2009-Jan-02 14:25:28
ThemeManagerImpl.class 2009-Sep-04 03:12:31
ThemeManagerImpl$1.class 2009-Sep-04 03:12:31