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    }