1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 package com.sun.star.report.pentaho.parser.office; 24 25 import com.sun.star.report.pentaho.OfficeNamespaces; 26 import com.sun.star.report.pentaho.model.OfficeDocument; 27 import com.sun.star.report.pentaho.model.OfficeStylesCollection; 28 import com.sun.star.report.pentaho.parser.style.OfficeStylesReadHandler; 29 30 import org.apache.commons.logging.Log; 31 import org.apache.commons.logging.LogFactory; 32 33 import org.jfree.report.JFreeReport; 34 35 import org.pentaho.reporting.libraries.resourceloader.Resource; 36 import org.pentaho.reporting.libraries.resourceloader.ResourceException; 37 import org.pentaho.reporting.libraries.resourceloader.ResourceKey; 38 import org.pentaho.reporting.libraries.resourceloader.ResourceKeyCreationException; 39 import org.pentaho.reporting.libraries.resourceloader.ResourceManager; 40 import org.pentaho.reporting.libraries.xmlns.parser.AbstractXmlReadHandler; 41 import org.pentaho.reporting.libraries.xmlns.parser.XmlReadHandler; 42 43 import org.xml.sax.Attributes; 44 import org.xml.sax.SAXException; 45 46 /** 47 * This is the root handler for the document context. The 48 * 'office:document-context' element is encountered, if the document is split 49 * into separate files. 50 * <p/> 51 * Alternativly, there is the option to keep everything in one file. The root 52 * element for that format is 'office:document'. 53 */ 54 public class DocumentContentReadHandler extends AbstractXmlReadHandler 55 { 56 57 private static final Log LOGGER = LogFactory.getLog(DocumentContentReadHandler.class); 58 private OfficeDocument report; 59 private FontFaceDeclsReadHandler fontFaceReadHandler; 60 private BodyReadHandler bodyReadHandler; 61 private OfficeStylesCollection officeStylesCollection; 62 DocumentContentReadHandler()63 public DocumentContentReadHandler() 64 { 65 } 66 67 /** 68 * Starts parsing. 69 * 70 * @param attrs the attributes. 71 * @throws org.xml.sax.SAXException if there is a parsing error. 72 */ startParsing(final Attributes attrs)73 protected void startParsing(final Attributes attrs) 74 throws SAXException 75 { 76 super.startParsing(attrs); 77 // parse the external 'styles.xml' if it exists 78 // parse the external 'meta.xml' if it exists 79 // parse the external 'settings.xml' if it exists 80 this.report = parseContentXml(); 81 this.report.setVirtual(true); 82 this.report.setType("document-content"); 83 this.report.setNamespace(OfficeNamespaces.OFFICE_NS); 84 this.report.setVirtual(true); 85 this.officeStylesCollection = parseStylesXml(); 86 } 87 parseStylesXml()88 private OfficeStylesCollection parseStylesXml() 89 { 90 final ResourceKey contextKey = getRootHandler().getContext(); 91 final ResourceManager resourceManager = getRootHandler().getResourceManager(); 92 93 try 94 { 95 final ResourceKey key = 96 resourceManager.deriveKey(contextKey, "styles.xml"); 97 final Resource resource = 98 resourceManager.create(key, contextKey, OfficeStylesCollection.class); 99 final OfficeStylesCollection styles = 100 (OfficeStylesCollection) resource.getResource(); 101 if (styles != null) 102 { 103 return styles; 104 } 105 } 106 catch (ResourceKeyCreationException e) 107 { 108 // ignore .. 109 LOGGER.debug("Failed to create resource-key for 'styles.xml'. Ignoring.", e); 110 } 111 catch (ResourceException e) 112 { 113 // ignore .. 114 LOGGER.debug("Failed to parse resource for 'styles.xml'. Ignoring.", e); 115 } 116 117 return new OfficeStylesCollection(); 118 } 119 parseContentXml()120 private OfficeDocument parseContentXml() 121 { 122 // Check whether this is a content.xml. 123 if (!OfficeNamespaces.OFFICE_NS.equals(getUri()) || "document-content".equals(getTagName())) 124 { 125 return new OfficeDocument(); 126 } 127 128 // we may have to parse an existing content.xml. 129 final ResourceKey contextKey = getRootHandler().getContext(); 130 final ResourceManager resourceManager = getRootHandler().getResourceManager(); 131 try 132 { 133 final ResourceKey key = 134 resourceManager.deriveKey(contextKey, "content.xml"); 135 final Resource resource = 136 resourceManager.create(key, contextKey, JFreeReport.class); 137 final OfficeDocument doc = (OfficeDocument) resource.getResource(); 138 if (doc != null) 139 { 140 return doc; 141 } 142 } 143 catch (ResourceKeyCreationException e) 144 { 145 // ignore .. 146 LOGGER.debug("Failed to create resource-key for 'content.xml'. Ignoring."); 147 } 148 catch (ResourceException e) 149 { 150 // ignore .. 151 LOGGER.debug("Failed to parse resource for 'content.xml'. Ignoring."); 152 } 153 return new OfficeDocument(); 154 155 } 156 157 /** 158 * Returns the handler for a child element. 159 * 160 * @param tagName the tag name. 161 * @param atts the attributes. 162 * @return the handler or null, if the tagname is invalid. 163 * 164 * @throws org.xml.sax.SAXException if there is a parsing error. 165 */ getHandlerForChild(final String uri, final String tagName, final Attributes atts)166 protected XmlReadHandler getHandlerForChild(final String uri, 167 final String tagName, 168 final Attributes atts) 169 throws SAXException 170 { 171 if (OfficeNamespaces.OFFICE_NS.equals(uri)) 172 { 173 if ("font-face-decls".equals(tagName)) 174 { 175 if (fontFaceReadHandler == null) 176 { 177 fontFaceReadHandler = new FontFaceDeclsReadHandler(officeStylesCollection.getFontFaceDecls()); 178 } 179 return fontFaceReadHandler; 180 } 181 else if ("automatic-styles".equals(tagName)) 182 { 183 return new OfficeStylesReadHandler(officeStylesCollection.getAutomaticStyles()); 184 } 185 else if ("styles".equals(tagName)) 186 { 187 return new OfficeStylesReadHandler(officeStylesCollection.getCommonStyles()); 188 } 189 else if ("master-styles".equals(tagName)) 190 { 191 return new MasterStylesReadHandler(officeStylesCollection.getMasterStyles()); 192 } 193 else if ("body".equals(tagName)) 194 { 195 bodyReadHandler = new BodyReadHandler(); 196 return bodyReadHandler; 197 } 198 } 199 return null; 200 } 201 202 /** 203 * Done parsing. 204 * 205 * @throws org.xml.sax.SAXException if there is a parsing error. 206 */ doneParsing()207 protected void doneParsing() 208 throws SAXException 209 { 210 // The office-document is the only node of the report. It allows us to 211 // switch the layout-processing implementation later on. 212 213 report.setStylesCollection(officeStylesCollection); 214 215 if (bodyReadHandler != null) 216 { 217 report.addNode(bodyReadHandler.getElement()); 218 } 219 } 220 221 /** 222 * Returns the object for this element or null, if this element does not 223 * create an object. 224 * 225 * @return the object. 226 */ getObject()227 public Object getObject() 228 throws SAXException 229 { 230 return report; 231 } 232 } 233