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,v 1.14 2007/04/01 18:49:25 taqua Exp $
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 public 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 (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 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(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(String uri)
269 {
270 if (uri == null)
271 {
272 return null;
273 }
274 return namespaces.getDefinition(uri);
275 }
276
277
278 protected void handleAttributes(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 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 (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 }