Author: snoopdave
Date: Mon Nov 21 03:32:29 2011
New Revision: 1204343
URL: http://svn.apache.org/viewvc?rev=1204343&view=rev
Log:
Hack to allow old Roller themes to work with Roller 5.1
Modified:
roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/SharedThemeFromDir.java
roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/ThemeMetadataParser.java
Modified:
roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/SharedThemeFromDir.java
URL:
http://svn.apache.org/viewvc/roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/SharedThemeFromDir.java?rev=1204343&r1=1204342&r2=1204343&view=diff
==============================================================================
---
roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/SharedThemeFromDir.java
(original)
+++
roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/SharedThemeFromDir.java
Mon Nov 21 03:32:29 2011
@@ -176,212 +176,208 @@ public class SharedThemeFromDir extends
}
- /**
- * Load all the elements of this theme from disk and cache them.
- */
- private void loadThemeFromDisk() throws ThemeInitializationException {
-
- log.debug("Parsing theme descriptor for "+this.themeDir);
-
- ThemeMetadata themeMetadata = null;
- try {
- // lookup theme descriptor and parse it
- ThemeMetadataParser parser = new ThemeMetadataParser();
- InputStream is = new FileInputStream(this.themeDir +
File.separator + "theme.xml");
- themeMetadata = parser.unmarshall(is);
- } catch (Exception ex) {
- throw new ThemeInitializationException("Unable to parse theme
descriptor for theme "+this.themeDir, ex);
- }
-
- log.debug("Loading Theme "+themeMetadata.getName());
-
- // use parsed theme descriptor to load Theme data
- setId(themeMetadata.getId());
- setName(themeMetadata.getName());
- setDescription(themeMetadata.getName());
- setType(themeMetadata.getType());
- setAuthor(themeMetadata.getAuthor());
- setLastModified(null);
- setEnabled(true);
-
- // load resource representing preview image
- File previewFile = new File(this.themeDir + File.separator +
themeMetadata.getPreviewImage());
- if(!previewFile.exists() || !previewFile.canRead()) {
- log.warn("Couldn't read theme [" + this.getName() + "] preview
image file ["+themeMetadata.getPreviewImage()+"]");
- } else {
- this.previewImage = new
SharedThemeResourceFromDir(themeMetadata.getPreviewImage(), previewFile);
- }
+ /**
+ * Load all the elements of this theme from disk and cache them.
+ */
+ private void loadThemeFromDisk() throws ThemeInitializationException {
+
+ log.debug("Parsing theme descriptor for " + this.themeDir);
+
+ ThemeMetadata themeMetadata = null;
+ try {
+ // lookup theme descriptor and parse it
+ ThemeMetadataParser parser = new ThemeMetadataParser();
+ InputStream is = new FileInputStream(this.themeDir +
File.separator + "theme.xml");
+ themeMetadata = parser.unmarshall(is);
+ } catch (Exception ex) {
+ throw new ThemeInitializationException("Unable to parse
theme descriptor for theme " + this.themeDir, ex);
+ }
+
+ log.debug("Loading Theme " + themeMetadata.getName());
+
+ // use parsed theme descriptor to load Theme data
+ setId(themeMetadata.getId());
+ setName(themeMetadata.getName());
+ setDescription(themeMetadata.getName());
+ setType(themeMetadata.getType());
+ setAuthor(themeMetadata.getAuthor());
+ setLastModified(null);
+ setEnabled(true);
+
+ // load resource representing preview image
+ File previewFile = new File(this.themeDir + File.separator +
themeMetadata.getPreviewImage());
+ if (!previewFile.exists() || !previewFile.canRead()) {
+ log.warn("Couldn't read theme [" + this.getName() + "]
preview image file [" + themeMetadata.getPreviewImage() + "]");
+ } else {
+ this.previewImage = new
SharedThemeResourceFromDir(themeMetadata.getPreviewImage(), previewFile);
+ }
+
+ //avaialble types in the Roller
+ List<String> availableTypesList = new ArrayList<String>();
+ availableTypesList.add("standard");
+ availableTypesList.add("mobile");
+
+ // load stylesheet if possible
+ if (themeMetadata.getStylesheet() != null) {
+
+ ThemeMetadataTemplate stylesheetTmpl =
themeMetadata.getStylesheet();
+ // getting the template codes for available types
+ ThemeMetadataTemplateCode standardTemplateCode =
stylesheetTmpl.getTemplateCodeTable().get("standard");
+ ThemeMetadataTemplateCode mobileTemplateCode =
stylesheetTmpl.getTemplateCodeTable().get("mobile");
+
+ // If no template code present for any type
+ if (standardTemplateCode == null && mobileTemplateCode
== null) {
+ throw new ThemeInitializationException("Error
in getting template codes for template");
+ } else if (mobileTemplateCode == null) {
+ //cloning the standard template code if no
mobile is present
+ mobileTemplateCode = new
ThemeMetadataTemplateCode();
+
mobileTemplateCode.setContentsFile(standardTemplateCode.getContentsFile());
+
mobileTemplateCode.setContentType(standardTemplateCode.getContentType());
+
mobileTemplateCode.setTemplateLang(standardTemplateCode.getTemplateLang());
+ mobileTemplateCode.setType("mobile");
- //avaialble types in the Roller
- List<String> availableTypesList = new ArrayList<String>();
- availableTypesList.add("standard");
- availableTypesList.add("mobile");
-
- // load stylesheet if possible
- if(themeMetadata.getStylesheet() != null) {
-
- ThemeMetadataTemplate stylesheetTmpl =
themeMetadata.getStylesheet();
- //getting the template codes for available types
- ThemeMetadataTemplateCode standardTemplateCode=
stylesheetTmpl.getTemplateCodeTable().get("standard");
- ThemeMetadataTemplateCode mobileTemplateCode=
stylesheetTmpl.getTemplateCodeTable().get("mobile");
-
- //If no template code present for any type
- if (standardTemplateCode == null && mobileTemplateCode == null) {
- throw new ThemeInitializationException("Error in getting
template codes for template");
- } else if(mobileTemplateCode == null){
- //cloning the standard template code if no mobile is present
- mobileTemplateCode = new ThemeMetadataTemplateCode();
-
mobileTemplateCode.setContentsFile(standardTemplateCode.getContentsFile());
-
mobileTemplateCode.setContentType(standardTemplateCode.getContentType());
-
mobileTemplateCode.setTemplateLang(standardTemplateCode.getTemplateLang());
- mobileTemplateCode.setType("mobile");
+ stylesheetTmpl.addTemplateCode("mobile",
mobileTemplateCode);
+ }
- stylesheetTmpl.addTemplateCode("mobile",mobileTemplateCode);
- }
+ // construct File object from path
+ // we are getting the file path from standard as the
default and load it to initially.
+ File templateFile = new File(this.themeDir +
File.separator
+ +
standardTemplateCode.getContentsFile());
+
+ // read stylesheet contents
+ String contents = loadTemplateFile(templateFile);
+ if (contents == null) {
+ // if we don't have any contents then skip this
one
+ log.error("Couldn't load stylesheet theme [" +
this.getName() + "] template file [" + templateFile + "]");
+ } else {
+
+ // construct ThemeTemplate representing this
file
+ // here we set content and template language
from standard template code assuming it is the default
+ SharedThemeTemplate theme_template = new
SharedThemeTemplate(
+ this,
+ themeMetadata.getId() + ":" +
stylesheetTmpl.getName(),
+ WeblogTemplate.ACTION_CUSTOM,
+ stylesheetTmpl.getName(),
+ stylesheetTmpl.getDescription(),
+ contents,
+ stylesheetTmpl.getLink(),
+ new
Date(templateFile.lastModified()),
+
standardTemplateCode.getTemplateLang(),
+ false,
+ false);
+
+
+ for (String type : availableTypesList) {
+ WeblogTemplateCode templateCode =
createTemplateCode(theme_template.getId(),
stylesheetTmpl.getTemplateCode(type));
+
+ theme_template.addTemplateCode(type,
templateCode);
+ }
+ // store it
+ this.stylesheet = theme_template;
- // construct File object from path
- // we are getting the file path from standard as the default and
load it to initially.
- File templateFile = new File(this.themeDir + File.separator +
- standardTemplateCode.getContentsFile());
-
- // read stylesheet contents
- String contents = loadTemplateFile(templateFile);
- if(contents == null) {
- // if we don't have any contents then skip this one
- log.error("Couldn't load stylesheet theme [" + this.getName()
+ "] template file ["+templateFile+"]");
- } else {
-
- // construct ThemeTemplate representing this file
- // here we set content and template language from standard
template code assuming it is the default
- SharedThemeTemplate theme_template = new SharedThemeTemplate(
- this,
- themeMetadata.getId()+":"+stylesheetTmpl.getName(),
- WeblogTemplate.ACTION_CUSTOM,
- stylesheetTmpl.getName(),
- stylesheetTmpl.getDescription(),
- contents,
- stylesheetTmpl.getLink(),
- new Date(templateFile.lastModified()),
- standardTemplateCode.getTemplateLang(),
- false,
- false);
-
-
- for (String type : availableTypesList) {
- WeblogTemplateCode templateCode =
createTemplateCode(theme_template.getId(), stylesheetTmpl.
- getTemplateCode(type));
-
- theme_template.addTemplateCode(type, templateCode);
- }
- // store it
- this.stylesheet = theme_template;
+ addTemplate(theme_template);
+ }
- addTemplate(theme_template);
- }
-
- // Set Last Modified
+ // Set Last Modified
setLastModified(new Date(templateFile.lastModified()));
-
- }
-
- // go through static resources and add them to the theme
- String resourcePath = null;
- Iterator resourcesIter = themeMetadata.getResources().iterator();
- while (resourcesIter.hasNext()) {
- resourcePath = (String) resourcesIter.next();
-
- // construct ThemeResource object from resource
- File resourceFile = new File(this.themeDir + File.separator +
resourcePath);
-
- // Continue reading theme even if problem encountered with one file
- if(!resourceFile.exists() || !resourceFile.canRead()) {
- log.warn("Couldn't read theme [" + this.getName() + "]
resource file ["+resourcePath+"]");
- continue;
- }
-
- // add it to the theme
- setResource(resourcePath, new
SharedThemeResourceFromDir(resourcePath, resourceFile));
-
- // Set Last Modified
+
+ }
+
+ // go through static resources and add them to the theme
+ String resourcePath = null;
+ Iterator resourcesIter =
themeMetadata.getResources().iterator();
+ while (resourcesIter.hasNext()) {
+ resourcePath = (String) resourcesIter.next();
+
+ // construct ThemeResource object from resource
+ File resourceFile = new File(this.themeDir +
File.separator + resourcePath);
+
+ // Continue reading theme even if problem encountered
with one file
+ if (!resourceFile.exists() || !resourceFile.canRead()) {
+ log.warn("Couldn't read theme [" +
this.getName() + "] resource file [" + resourcePath + "]");
+ continue;
+ }
+
+ // add it to the theme
+ setResource(resourcePath, new
SharedThemeResourceFromDir(resourcePath, resourceFile));
+
+ // Set Last Modified
Date lstModified = new
Date(resourceFile.lastModified());
if (getLastModified() == null
||
lstModified.after(getLastModified())) {
setLastModified(lstModified);
}
-
- }
-
- // go through templates and read in contents to a ThemeTemplate
- SharedThemeTemplate theme_template = null;
- ThemeMetadataTemplate templateMetadata = null;
- Iterator templatesIter = themeMetadata.getTemplates().iterator();
- while (templatesIter.hasNext()) {
- templateMetadata = (ThemeMetadataTemplate) templatesIter.next();
-
- //getting the template codes for available types
- ThemeMetadataTemplateCode standardTemplateCode=
templateMetadata.getTemplateCodeTable().get("standard");
- ThemeMetadataTemplateCode mobileTemplateCode=
templateMetadata.getTemplateCodeTable().get("mobile");
-
- //If no template code present for any type
- if(standardTemplateCode ==null && mobileTemplateCode == null){
- throw new ThemeInitializationException("Error in getting
template codes for template");
- }
- else if(mobileTemplateCode == null){
- //cloning the standard template code if no mobile is present
- mobileTemplateCode = new ThemeMetadataTemplateCode();
-
mobileTemplateCode.setContentsFile(standardTemplateCode.getContentsFile());
-
mobileTemplateCode.setContentType(standardTemplateCode.getContentType());
-
mobileTemplateCode.setTemplateLang(standardTemplateCode.getTemplateLang());
- mobileTemplateCode.setType("mobile");
+ }
- templateMetadata.addTemplateCode("mobile",mobileTemplateCode);
- }
-
- // construct File object from path
- File templateFile = new File(this.themeDir + File.separator +
- standardTemplateCode.getContentsFile());
-
- String contents = loadTemplateFile(templateFile);
- if(contents == null) {
- // if we don't have any contents then skip this one
- throw new ThemeInitializationException("Couldn't load theme ["
+ this.getName() + "] template file ["+templateFile+"]");
- }
-
- // construct ThemeTemplate representing this file
- theme_template = new SharedThemeTemplate(
- this,
- themeMetadata.getId()+":"+templateMetadata.getName(),
- templateMetadata.getAction(),
- templateMetadata.getName(),
- templateMetadata.getDescription(),
- contents,
- templateMetadata.getLink(),
- new Date(templateFile.lastModified()),
- standardTemplateCode.getTemplateLang(),
- templateMetadata.isHidden(),
- templateMetadata.isNavbar()
- );
-
- for (String type : availableTypesList) {
- WeblogTemplateCode templateCode =
createTemplateCode(theme_template.getId(),
- templateMetadata.getTemplateCode(type));
+ // go through templates and read in contents to a ThemeTemplate
+ SharedThemeTemplate theme_template = null;
+ ThemeMetadataTemplate templateMetadata = null;
+ Iterator templatesIter =
themeMetadata.getTemplates().iterator();
+ while (templatesIter.hasNext()) {
+ templateMetadata = (ThemeMetadataTemplate)
templatesIter.next();
+
+ //getting the template codes for available types
+ ThemeMetadataTemplateCode standardTemplateCode =
templateMetadata.getTemplateCodeTable().get("standard");
+ ThemeMetadataTemplateCode mobileTemplateCode =
templateMetadata.getTemplateCodeTable().get("mobile");
+
+ //If no template code present for any type
+ if (standardTemplateCode == null && mobileTemplateCode
== null) {
+ throw new ThemeInitializationException("Error
in getting template codes for template");
+ } else if (mobileTemplateCode == null) {
+ //cloning the standard template code if no
mobile is present
+ mobileTemplateCode = new
ThemeMetadataTemplateCode();
+
mobileTemplateCode.setContentsFile(standardTemplateCode.getContentsFile());
+
mobileTemplateCode.setContentType(standardTemplateCode.getContentType());
+
mobileTemplateCode.setTemplateLang(standardTemplateCode.getTemplateLang());
+ mobileTemplateCode.setType("mobile");
- theme_template.addTemplateCode(type, templateCode);
- }
+ templateMetadata.addTemplateCode("mobile",
mobileTemplateCode);
+ }
+
+ // construct File object from path
+ File templateFile = new File(this.themeDir +
File.separator
+ +
standardTemplateCode.getContentsFile());
+
+ String contents = loadTemplateFile(templateFile);
+ if (contents == null) {
+ // if we don't have any contents then skip this
one
+ throw new
ThemeInitializationException("Couldn't load theme [" + this.getName() + "]
template file [" + templateFile + "]");
+ }
+
+ // construct ThemeTemplate representing this file
+ theme_template = new SharedThemeTemplate(
+ this,
+ themeMetadata.getId() + ":" +
templateMetadata.getName(),
+ templateMetadata.getAction(),
+ templateMetadata.getName(),
+ templateMetadata.getDescription(),
+ contents,
+ templateMetadata.getLink(),
+ new Date(templateFile.lastModified()),
+ standardTemplateCode.getTemplateLang(),
+ templateMetadata.isHidden(),
+ templateMetadata.isNavbar());
+
+ for (String type : availableTypesList) {
+ WeblogTemplateCode templateCode =
createTemplateCode(theme_template.getId(),
+
templateMetadata.getTemplateCode(type));
- // add it to the theme
- addTemplate(theme_template);
-
- // Set Last Modified
+ theme_template.addTemplateCode(type,
templateCode);
+ }
+
+ // add it to the theme
+ addTemplate(theme_template);
+
+ // Set Last Modified
Date lstModified = new
Date(templateFile.lastModified());
if (getLastModified() == null
||
lstModified.after(getLastModified())) {
setLastModified(lstModified);
}
- }
- }
+ }
+ }
/**
Modified:
roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/ThemeMetadataParser.java
URL:
http://svn.apache.org/viewvc/roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/ThemeMetadataParser.java?rev=1204343&r1=1204342&r2=1204343&view=diff
==============================================================================
---
roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/ThemeMetadataParser.java
(original)
+++
roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/ThemeMetadataParser.java
Mon Nov 21 03:32:29 2011
@@ -29,6 +29,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
/**
@@ -37,7 +39,8 @@ import java.util.List;
* This class unmarshalls a theme descriptor into a set of objects.
*/
public class ThemeMetadataParser {
-
+
+ private static Log log = LogFactory.getLog(ThemeMetadataParser.class);
/**
* Unmarshall the given input stream into our defined
@@ -114,65 +117,81 @@ public class ThemeMetadataParser {
}
- private ThemeMetadataTemplate elementToTemplateMetadata(Element element)
- throws ThemeParsingException {
-
- ThemeMetadataTemplate template = new ThemeMetadataTemplate();
-
- template.setAction(element.getAttributeValue("action"));
- template.setName(element.getChildText("name"));
- template.setDescription(element.getChildText("description"));
- template.setLink(element.getChildText("link"));
+ private ThemeMetadataTemplate elementToTemplateMetadata(Element element)
+ throws ThemeParsingException {
- //parsing tempaltecode segment
- List templateCodeList = element.getChildren("templateCode");
- Iterator templCodeitr = templateCodeList.iterator();
+ ThemeMetadataTemplate template = new ThemeMetadataTemplate();
- while (templCodeitr.hasNext()){
- Element templateCodeElement = (Element) templCodeitr.next();
+ template.setAction(element.getAttributeValue("action"));
+ template.setName(element.getChildText("name"));
+ template.setDescription(element.getChildText("description"));
+ template.setLink(element.getChildText("link"));
+
template.setTemplateLanguage(element.getChildText("templateLanguage"));
+ template.setContentType(element.getChildText("contentType"));
+ template.setContentsFile(element.getChildText("contentsFile"));
+
+ //parsing tempaltecode segment
+ List templateCodeList = element.getChildren("templateCode");
+ Iterator templCodeitr = templateCodeList.iterator();
+
+ boolean roller50format = false;
+ while (templCodeitr.hasNext()) {
+ Element templateCodeElement = (Element)
templCodeitr.next();
+
+ ThemeMetadataTemplateCode templateCode = new
ThemeMetadataTemplateCode();
+
templateCode.setTemplateLang(templateCodeElement.getChildText("templateLanguage"));
+
templateCode.setContentsFile(templateCodeElement.getChildText("contentsFile"));
+
templateCode.setContentType(templateCodeElement.getChildText("contentType"));
+
templateCode.setType(templateCodeElement.getChildText("type"));
+
+ // validating template code
+ if
(StringUtils.isEmpty(templateCode.getContentsFile())) {
+ throw new ThemeParsingException("templateCode
must contain a 'contentsFile' element");
+ }
+ if
(StringUtils.isEmpty(templateCode.getTemplateLang())) {
+ throw new ThemeParsingException("templateCode
must contain a 'templateLanguage' element");
+ }
+ if (StringUtils.isEmpty(templateCode.getType())) {
+ throw new ThemeParsingException("templateCode
must contain a 'type' element");
+ }
+ template.addTemplateCode(templateCode.getType(),
templateCode);
+
+ // if theme has type, then it's roller50format
+ roller50format = true;
+ }
+
+ // hack to ensure old format themes still work
+ if (!roller50format) {
+ ThemeMetadataTemplateCode templateCode = new
ThemeMetadataTemplateCode();
+
templateCode.setTemplateLang(template.getTemplateLanguage());
+
templateCode.setContentsFile(template.getContentsFile());
+ templateCode.setContentType(template.getContentType());
+ templateCode.setType("standard");
+ template.addTemplateCode("standard", templateCode);
+ }
+
+ String navbar = element.getChildText("navbar");
+ if ("true".equalsIgnoreCase(navbar)) {
+ template.setNavbar(true);
+ }
+
+ String hidden = element.getChildText("hidden");
+ if ("true".equalsIgnoreCase(hidden)) {
+ template.setHidden(true);
+ }
+
+ // validate template
+ if (StringUtils.isEmpty(template.getAction())) {
+ throw new ThemeParsingException("templates must contain
an 'action' attribute");
+ }
+ if (StringUtils.isEmpty(template.getName())) {
+ throw new ThemeParsingException("templates must contain
a 'name' element");
+ }
- ThemeMetadataTemplateCode templateCode = new
ThemeMetadataTemplateCode();
-
templateCode.setTemplateLang(templateCodeElement.getChildText("templateLanguage"));
-
templateCode.setContentsFile(templateCodeElement.getChildText("contentsFile"));
-
templateCode.setContentType(templateCodeElement.getChildText("contentType"));
- templateCode.setType(templateCodeElement.getChildText("type"));
- // validating template code
- if (StringUtils.isEmpty(templateCode.getContentsFile())) {
- throw new ThemeParsingException("templateCode must contain a
'contentsFile' element");
- }
- if(StringUtils.isEmpty(templateCode.getTemplateLang())) {
- throw new ThemeParsingException("templateCode must contain a
'templateLanguage' element");
- }
- if(StringUtils.isEmpty(templateCode.getType())) {
- throw new ThemeParsingException("templateCode must contain a
'type' element");
- }
-
- template.addTemplateCode(templateCode.getType(),templateCode);
- }
-
- String navbar = element.getChildText("navbar");
- if("true".equalsIgnoreCase(navbar)) {
- template.setNavbar(true);
- }
-
- String hidden = element.getChildText("hidden");
- if("true".equalsIgnoreCase(hidden)) {
- template.setHidden(true);
- }
-
- // validate template
- if(StringUtils.isEmpty(template.getAction())) {
- throw new ThemeParsingException("templates must contain an
'action' attribute");
- }
- if(StringUtils.isEmpty(template.getName())) {
- throw new ThemeParsingException("templates must contain a 'name'
element");
- }
-
-
- return template;
- }
+ return template;
+ }
private ThemeMetadataTemplate elementToStylesheet(Element element)
@@ -188,6 +207,7 @@ public class ThemeMetadataParser {
List templateCodeList = element.getChildren("templateCode");
Iterator templCodeitr = templateCodeList.iterator();
+ boolean roller50format = false;
while (templCodeitr.hasNext()){
Element templateCodeElement = (Element) templCodeitr.next();
@@ -205,11 +225,24 @@ public class ThemeMetadataParser {
throw new ThemeParsingException("stylesheet must contain a
'templateLanguage' element");
}
if (StringUtils.isEmpty(templateCode.getType())) {
- throw new ThemeParsingException("templateCode must contain a
'type' element");
+ throw new ThemeParsingException("templateCode
must contain a 'type' element");
}
template.addTemplateCode(templateCode.getType(), templateCode);
+
+ // if theme has type, then it's roller50format
+ roller50format = true;
}
+ // hack to ensure old format themes still work
+ if (!roller50format) {
+ ThemeMetadataTemplateCode templateCode = new
ThemeMetadataTemplateCode();
+
templateCode.setTemplateLang(template.getTemplateLanguage());
+
templateCode.setContentsFile(template.getContentsFile());
+ templateCode.setContentType(template.getContentType());
+ templateCode.setType("standard");
+ template.addTemplateCode("standard", templateCode);
+ }
+
// validate template
if(StringUtils.isEmpty(template.getName())) {
throw new ThemeParsingException("stylesheet must contain a 'name'
element");