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: BufferedReportTarget.java 2725 2007-04-01 18:49:29Z taqua $
027     * ------------
028     * (C) Copyright 2000-2005, by Object Refinery Limited.
029     * (C) Copyright 2005-2007, by Pentaho Corporation.
030     */
031    
032    package org.jfree.report.flow.layoutprocessor;
033    
034    import java.util.ArrayList;
035    
036    import org.jfree.layouting.namespace.NamespaceDefinition;
037    import org.jfree.layouting.util.AttributeMap;
038    import org.jfree.report.DataFlags;
039    import org.jfree.report.DataSourceException;
040    import org.jfree.report.ReportProcessingException;
041    import org.jfree.report.flow.ReportStructureRoot;
042    import org.jfree.report.flow.ReportTarget;
043    
044    /**
045     * Todo: Document me!
046     *
047     * @author Thomas Morgner
048     * @since 05.03.2007
049     */
050    public class BufferedReportTarget implements ReportTarget, Cloneable
051    {
052      public static class RecordedCall
053      {
054        private int methodId;
055        private Object parameters;
056    
057        public RecordedCall(final int method, final Object parameters)
058        {
059          this.methodId = method;
060          this.parameters = parameters;
061        }
062    
063        public int getMethod()
064        {
065          return methodId;
066        }
067    
068        public Object getParameters()
069        {
070          return parameters;
071        }
072      }
073    
074      private static final int MTH_START_REPORT = 1;
075      private static final int MTH_START_ELEMENT = 2;
076      private static final int MTH_PROCESS_TEXT = 3;
077      private static final int MTH_PROCESS_CONTENT = 4;
078      private static final int MTH_END_ELEMENT = 5;
079      private static final int MTH_END_REPORT = 6;
080    
081      private ReportTarget target;
082      private ArrayList calls;
083    
084      public BufferedReportTarget()
085      {
086        this.calls = new ArrayList();
087      }
088    
089      public ReportTarget getTarget()
090      {
091        return target;
092      }
093    
094      public void setTarget(final ReportTarget target)
095      {
096        this.target = target;
097      }
098    
099      public void startReport(final ReportStructureRoot report)
100          throws DataSourceException, ReportProcessingException
101      {
102        calls.add(new RecordedCall
103            (BufferedReportTarget.MTH_START_REPORT, report));
104      }
105    
106      public void startElement(final AttributeMap attrs)
107          throws DataSourceException, ReportProcessingException
108      {
109        try
110        {
111          calls.add(new RecordedCall
112              (BufferedReportTarget.MTH_START_ELEMENT, attrs.clone()));
113        }
114        catch (CloneNotSupportedException e)
115        {
116          throw new ReportProcessingException("Failed to clone attributes", e);
117        }
118      }
119    
120      public void processText(final String text)
121          throws DataSourceException, ReportProcessingException
122      {
123        calls.add(new RecordedCall
124            (BufferedReportTarget.MTH_PROCESS_TEXT, text));
125      }
126    
127      public void processContent(final DataFlags value)
128          throws DataSourceException, ReportProcessingException
129      {
130        calls.add(new RecordedCall
131            (BufferedReportTarget.MTH_PROCESS_CONTENT, value));
132      }
133    
134      public void endElement(final AttributeMap attrs)
135          throws DataSourceException, ReportProcessingException
136      {
137        try
138        {
139          calls.add(new RecordedCall
140              (BufferedReportTarget.MTH_END_ELEMENT, attrs.clone()));
141        }
142        catch (CloneNotSupportedException e)
143        {
144          throw new ReportProcessingException("Failed to clone attributes", e);
145        }
146      }
147    
148      public void endReport(final ReportStructureRoot report)
149          throws DataSourceException, ReportProcessingException
150      {
151        calls.add(new RecordedCall
152            (BufferedReportTarget.MTH_END_REPORT, report));
153      }
154    
155      public String getExportDescriptor()
156      {
157        return target.getExportDescriptor();
158      }
159    
160      public NamespaceDefinition getNamespaceByUri(final String uri)
161      {
162        return target.getNamespaceByUri(uri);
163      }
164    
165      public void commit()
166          throws ReportProcessingException
167      {
168        // ignored ..
169      }
170    
171      public void close(final ReportTarget target)
172          throws ReportProcessingException, DataSourceException
173      {
174        final RecordedCall[] objects = (RecordedCall[])
175            calls.toArray(new RecordedCall[calls.size()]);
176    
177        for (int i = 0; i < objects.length; i++)
178        {
179          final RecordedCall call = objects[i];
180          switch(call.getMethod())
181          {
182            case BufferedReportTarget.MTH_START_REPORT:
183            {
184              target.startReport((ReportStructureRoot) call.getParameters());
185              break;
186            }
187            case BufferedReportTarget.MTH_START_ELEMENT:
188            {
189              target.startElement((AttributeMap) call.getParameters());
190              break;
191            }
192            case BufferedReportTarget.MTH_PROCESS_TEXT:
193            {
194              target.processText((String) call.getParameters());
195              break;
196            }
197            case BufferedReportTarget.MTH_PROCESS_CONTENT:
198            {
199              target.processContent((DataFlags) call.getParameters());
200              break;
201            }
202            case BufferedReportTarget.MTH_END_ELEMENT:
203            {
204              target.endElement((AttributeMap) call.getParameters());
205              break;
206            }
207            case BufferedReportTarget.MTH_END_REPORT:
208            {
209              target.endReport((ReportStructureRoot) call.getParameters());
210              break;
211            }
212            default:
213              throw new IllegalStateException("Invalid call recorded.");
214          }
215        }
216      }
217    
218      public Object clone ()
219      {
220        try
221        {
222          final BufferedReportTarget o = (BufferedReportTarget) super.clone();
223          o.calls = (ArrayList) calls.clone();
224          return o;
225        }
226        catch (CloneNotSupportedException e)
227        {
228          throw new IllegalStateException("Clone failed");
229        }
230      }
231    }