001 /** 002 * ======================================== 003 * JFreeReport : a free Java report library 004 * ======================================== 005 * 006 * Project Info: http://reporting.pentaho.org/ 007 * 008 * (C) Copyright 2000-2007, by Object Refinery Limited, Pentaho Corporation and Contributors. 009 * 010 * This library is free software; you can redistribute it and/or modify it under the terms 011 * of the GNU Lesser General Public License as published by the Free Software Foundation; 012 * either version 2.1 of the License, or (at your option) any later version. 013 * 014 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 015 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 016 * See the GNU Lesser General Public License for more details. 017 * 018 * You should have received a copy of the GNU Lesser General Public License along with this 019 * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 020 * Boston, MA 02111-1307, USA. 021 * 022 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 023 * in the United States and other countries.] 024 * 025 * ------------ 026 * $Id: LibLayoutReportTarget.java 3525 2007-10-16 11:43:48Z tmorgner $ 027 * ------------ 028 * (C) Copyright 2000-2005, by Object Refinery Limited. 029 * (C) Copyright 2005-2007, by Pentaho Corporation. 030 */ 031 package org.jfree.report.flow; 032 033 import java.util.Iterator; 034 import java.util.Map; 035 036 import org.jfree.layouting.LayoutProcess; 037 import org.jfree.layouting.LayoutProcessState; 038 import org.jfree.layouting.StateException; 039 import org.jfree.layouting.input.style.StyleSheet; 040 import org.jfree.layouting.layouter.context.DocumentContext; 041 import org.jfree.layouting.layouter.feed.InputFeed; 042 import org.jfree.layouting.layouter.feed.InputFeedException; 043 import org.jfree.layouting.namespace.NamespaceCollection; 044 import org.jfree.layouting.namespace.NamespaceDefinition; 045 import org.jfree.layouting.output.OutputProcessor; 046 import org.jfree.layouting.util.AttributeMap; 047 import org.jfree.report.DataFlags; 048 import org.jfree.report.DataSourceException; 049 import org.jfree.report.JFreeReport; 050 import org.jfree.report.JFreeReportInfo; 051 import org.jfree.report.ReportProcessingException; 052 import org.jfree.resourceloader.ResourceKey; 053 import org.jfree.resourceloader.ResourceManager; 054 055 /** 056 * Creation-Date: 07.03.2006, 18:56:37 057 * 058 * @author Thomas Morgner 059 */ 060 public class LibLayoutReportTarget extends AbstractReportTarget 061 implements StatefullReportTarget 062 { 063 protected static class LibLayoutReportTargetState 064 implements ReportTargetState 065 { 066 private LayoutProcessState layoutProcess; 067 private ReportJob reportJob; 068 private ResourceKey baseResourceKey; 069 private ResourceManager resourceManager; 070 private NamespaceCollection namespaceCollection; 071 072 protected LibLayoutReportTargetState() 073 { 074 } 075 076 public void fill (final LibLayoutReportTarget target) throws StateException 077 { 078 this.layoutProcess = target.getLayoutProcess().saveState(); 079 this.reportJob = target.getReportJob(); 080 this.baseResourceKey = target.getBaseResource(); 081 this.resourceManager = target.getResourceManager(); 082 this.namespaceCollection = target.getNamespaces(); 083 } 084 085 public ReportTarget restore(final OutputProcessor out) 086 throws StateException 087 { 088 final LayoutProcess layoutProcess = this.layoutProcess.restore(out); 089 return new LibLayoutReportTarget(reportJob, 090 baseResourceKey, resourceManager, layoutProcess, namespaceCollection); 091 } 092 } 093 094 095 private InputFeed feed; 096 private NamespaceCollection namespaces; 097 private LayoutProcess layoutProcess; 098 099 /** 100 * 101 * @param reportJob 102 * @param baseResourceKey may be null, if the report has not gone through the parser 103 * @param resourceManager may be null, a generic resource manager will be built 104 * @param layoutProcess 105 */ 106 public LibLayoutReportTarget (final ReportJob reportJob, 107 final ResourceKey baseResourceKey, 108 final ResourceManager resourceManager, 109 final LayoutProcess layoutProcess) 110 { 111 super(reportJob, resourceManager, baseResourceKey); 112 113 if (layoutProcess == null) 114 { 115 throw new NullPointerException(); 116 } 117 this.layoutProcess = layoutProcess; 118 this.feed = layoutProcess.getInputFeed(); 119 } 120 121 protected LibLayoutReportTarget(final ReportJob reportJob, 122 final ResourceKey baseResource, 123 final ResourceManager resourceManager, 124 final LayoutProcess layoutProcess, 125 final NamespaceCollection namespaces) 126 { 127 this(reportJob, baseResource, resourceManager, layoutProcess); 128 this.namespaces = namespaces; 129 } 130 131 public ReportTargetState saveState() throws StateException 132 { 133 final LibLayoutReportTargetState state = new LibLayoutReportTargetState(); 134 state.fill(this); 135 return state; 136 } 137 138 public void commit() 139 { 140 141 } 142 143 public NamespaceCollection getNamespaces() 144 { 145 return namespaces; 146 } 147 148 public boolean isPagebreakEncountered() 149 { 150 return layoutProcess.isPagebreakEncountered(); 151 } 152 153 protected LayoutProcess getLayoutProcess() 154 { 155 return layoutProcess; 156 } 157 158 protected InputFeed getInputFeed () 159 { 160 return feed; 161 } 162 163 public void startReport (final ReportStructureRoot report) 164 throws DataSourceException, ReportProcessingException 165 { 166 try 167 { 168 final InputFeed feed = getInputFeed(); 169 feed.startDocument(); 170 feed.startMetaInfo(); 171 172 feed.addDocumentAttribute(DocumentContext.BASE_RESOURCE_ATTR, report.getBaseResource()); 173 feed.addDocumentAttribute(DocumentContext.RESOURCE_MANAGER_ATTR, report.getResourceManager()); 174 175 final String strictStyleMode = "false"; 176 if ("true".equals(strictStyleMode)) 177 { 178 feed.addDocumentAttribute(DocumentContext.STRICT_STYLE_MODE, Boolean.TRUE); 179 } 180 181 final NamespaceDefinition[] namespaces = createDefaultNameSpaces(); 182 for (int i = 0; i < namespaces.length; i++) 183 { 184 final NamespaceDefinition definition = namespaces[i]; 185 feed.startMetaNode(); 186 feed.setMetaNodeAttribute("type", "namespace"); 187 feed.setMetaNodeAttribute("definition", definition); 188 feed.endMetaNode(); 189 } 190 191 if (report instanceof JFreeReport) 192 { 193 final JFreeReport realReport = (JFreeReport) report; 194 final int size = realReport.getStyleSheetCount(); 195 for (int i = 0; i < size; i++) 196 { 197 final StyleSheet styleSheet = realReport.getStyleSheet(i); 198 feed.startMetaNode(); 199 feed.setMetaNodeAttribute("type", "style"); 200 feed.setMetaNodeAttribute("#content", styleSheet); 201 feed.endMetaNode(); 202 } 203 } 204 205 feed.endMetaInfo(); 206 this.namespaces = feed.getNamespaceCollection(); 207 } 208 catch (InputFeedException dse) 209 { 210 dse.printStackTrace(); 211 throw new ReportProcessingException("Failed to process inputfeed", dse); 212 } 213 214 } 215 216 public void startElement (final AttributeMap attrs) 217 throws DataSourceException, ReportProcessingException 218 { 219 try 220 { 221 final String namespace = ReportTargetUtil.getNamespaceFromAttribute(attrs); 222 final String type = ReportTargetUtil.getElemenTypeFromAttribute(attrs); 223 final InputFeed feed = getInputFeed(); 224 feed.startElement(namespace, type); 225 handleAttributes(attrs); 226 } 227 catch (InputFeedException e) 228 { 229 throw new ReportProcessingException("Failed to process inputfeed", e); 230 } 231 } 232 233 public void processText(final String text) 234 throws DataSourceException, ReportProcessingException 235 { 236 try 237 { 238 final InputFeed feed = getInputFeed(); 239 feed.addContent(text); 240 } 241 catch (InputFeedException e) 242 { 243 throw new ReportProcessingException("Failed to process inputfeed", e); 244 } 245 } 246 247 public void processContent (final DataFlags value) 248 throws DataSourceException, ReportProcessingException 249 { 250 final InputFeed feed = getInputFeed(); 251 try 252 { 253 feed.setAttribute(JFreeReportInfo.REPORT_NAMESPACE, "content", value.getValue()); 254 feed.setAttribute(JFreeReportInfo.REPORT_NAMESPACE, "isChanged", String.valueOf(value.isChanged())); 255 feed.setAttribute(JFreeReportInfo.REPORT_NAMESPACE, "isDate", String.valueOf(value.isDate())); 256 feed.setAttribute(JFreeReportInfo.REPORT_NAMESPACE, "isNegative", String.valueOf(value.isNegative())); 257 feed.setAttribute(JFreeReportInfo.REPORT_NAMESPACE, "isNull", String.valueOf(value.isNull())); 258 feed.setAttribute(JFreeReportInfo.REPORT_NAMESPACE, "isNumber", String.valueOf(value.isNumeric())); 259 feed.setAttribute(JFreeReportInfo.REPORT_NAMESPACE, "isPositive", String.valueOf(value.isPositive())); 260 feed.setAttribute(JFreeReportInfo.REPORT_NAMESPACE, "isZero", String.valueOf(value.isZero())); 261 } 262 catch (InputFeedException e) 263 { 264 throw new ReportProcessingException("Failed to process inputfeed", e); 265 } 266 } 267 268 public NamespaceDefinition getNamespaceByUri(final String uri) 269 { 270 if (uri == null) 271 { 272 return null; 273 } 274 return namespaces.getDefinition(uri); 275 } 276 277 278 protected void handleAttributes(final AttributeMap map) 279 throws ReportProcessingException 280 { 281 try 282 { 283 final InputFeed feed = getInputFeed(); 284 final String[] namespaces = map.getNameSpaces(); 285 for (int i = 0; i < namespaces.length; i++) 286 { 287 final String namespace = namespaces[i]; 288 final Map localAttrs = map.getAttributes(namespace); 289 final Iterator it = localAttrs.entrySet().iterator(); 290 while (it.hasNext()) 291 { 292 final Map.Entry entry = (Map.Entry) it.next(); 293 feed.setAttribute(namespace, (String) entry.getKey(), entry.getValue()); 294 } 295 } 296 } 297 catch (InputFeedException e) 298 { 299 throw new ReportProcessingException("Failed to set attribute", e); 300 } 301 } 302 303 public void endElement (final AttributeMap attrs) 304 throws DataSourceException, ReportProcessingException 305 { 306 final InputFeed feed = getInputFeed(); 307 try 308 { 309 feed.endElement(); 310 } 311 catch (InputFeedException e) 312 { 313 throw new ReportProcessingException("Failed to process inputfeed", e); 314 } 315 } 316 317 public void endReport (final ReportStructureRoot report) 318 throws DataSourceException, 319 ReportProcessingException 320 { 321 try 322 { 323 getInputFeed().endDocument(); 324 } 325 catch (InputFeedException e) 326 { 327 throw new ReportProcessingException("Failed to process inputfeed", e); 328 } 329 } 330 331 332 public void resetPagebreakFlag() 333 { 334 getInputFeed().resetPageBreakFlag(); 335 } 336 337 public String getExportDescriptor() 338 { 339 return getLayoutProcess().getOutputMetaData().getExportDescriptor(); 340 } 341 }