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: XmlPrintReportTarget.java,v 1.2 2007/04/01 18:49:26 taqua Exp $
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.raw;
033
034 import java.awt.Image;
035 import java.io.IOException;
036 import java.util.Iterator;
037 import java.util.Map;
038
039 import org.jfree.layouting.namespace.NamespaceDefinition;
040 import org.jfree.layouting.namespace.Namespaces;
041 import org.jfree.layouting.namespace.NamespaceCollection;
042 import org.jfree.layouting.namespace.DefaultNamespaceCollection;
043 import org.jfree.layouting.util.AttributeMap;
044 import org.jfree.layouting.LibLayoutBoot;
045 import org.jfree.report.DataFlags;
046 import org.jfree.report.DataSourceException;
047 import org.jfree.report.JFreeReportInfo;
048 import org.jfree.report.ReportProcessingException;
049 import org.jfree.report.util.AttributeNameGenerator;
050 import org.jfree.report.flow.ReportJob;
051 import org.jfree.report.flow.ReportStructureRoot;
052 import org.jfree.report.flow.ReportTarget;
053 import org.jfree.report.flow.ReportTargetUtil;
054 import org.jfree.xmlns.common.AttributeList;
055 import org.jfree.xmlns.writer.XmlWriter;
056 import org.jfree.xmlns.writer.XmlWriterSupport;
057
058 /**
059 * Todo: Document me!
060 *
061 * @author Thomas Morgner
062 * @since 20.03.2007
063 */
064 public class XmlPrintReportTarget implements ReportTarget
065 {
066 private ReportJob reportJob;
067 private XmlWriter writer;
068 private NamespaceCollection namespaces;
069 private AttributeNameGenerator namespacePrefixGenerator;
070
071 public XmlPrintReportTarget(final ReportJob job,
072 final XmlWriter writer)
073 {
074 this.reportJob = job;
075 this.writer = writer;
076
077 final NamespaceDefinition[] reportNamespaces = Namespaces.createFromConfig
078 (reportJob.getConfiguration(), "org.jfree.report.namespaces.", null);
079 final NamespaceDefinition[] layoutNamespaces = Namespaces.createFromConfig
080 (LibLayoutBoot.getInstance().getGlobalConfig(),
081 "org.jfree.layouting.namespaces.", null);
082 DefaultNamespaceCollection namespaces = new DefaultNamespaceCollection();
083 namespaces.addDefinitions(reportNamespaces);
084 namespaces.addDefinitions(layoutNamespaces);
085 this.namespaces = namespaces;
086 this.namespacePrefixGenerator = new AttributeNameGenerator();
087 }
088
089 public ReportJob getReportJob()
090 {
091 return reportJob;
092 }
093
094 public void startReport(final ReportStructureRoot report)
095 throws DataSourceException, ReportProcessingException
096 {
097 try
098 {
099 writer.writeComment("starting report");
100 }
101 catch (IOException e)
102 {
103 throw new ReportProcessingException("IOError", e);
104 }
105 }
106
107 public void startElement(final AttributeMap attrs)
108 throws DataSourceException, ReportProcessingException
109 {
110 final String namespace = ReportTargetUtil.getNamespaceFromAttribute(attrs);
111 final String elementType =
112 ReportTargetUtil.getElemenTypeFromAttribute(attrs);
113
114 try
115 {
116 final AttributeList attrList = buildAttributeList(attrs);
117 validateNamespace(namespace, attrList);
118 writer.writeTag(namespace, elementType, attrList,
119 XmlWriterSupport.OPEN);
120 }
121 catch (IOException e)
122 {
123 throw new ReportProcessingException("IOError", e);
124 }
125 }
126
127 public void processContent(final DataFlags value)
128 throws DataSourceException, ReportProcessingException
129 {
130 final Object rawvalue = value.getValue();
131 if (rawvalue == null)
132 {
133 return;
134 }
135
136 // special handler for image (possibly also for URL ..)
137 if (rawvalue instanceof Image)
138 {
139 // do nothing yet. We should define something for that later ..
140 return;
141 }
142
143 try
144 {
145 final String text = String.valueOf(rawvalue);
146 writer.writeText(XmlWriterSupport.normalize(text, false));
147 }
148 catch (IOException e)
149 {
150 throw new ReportProcessingException("Failed", e);
151 }
152 }
153
154 public void endElement(final AttributeMap attrs)
155 throws DataSourceException, ReportProcessingException
156 {
157 try
158 {
159 writer.writeCloseTag();
160 }
161 catch (IOException e)
162 {
163 throw new ReportProcessingException("IOError", e);
164 }
165 }
166
167 public void endReport(final ReportStructureRoot report)
168 throws DataSourceException, ReportProcessingException
169 {
170 try
171 {
172 writer.writeComment("starting report");
173 }
174 catch (IOException e)
175 {
176 throw new ReportProcessingException("IOError", e);
177 }
178 }
179
180 public NamespaceDefinition getNamespaceByUri(final String uri)
181 {
182 return namespaces.getDefinition(uri);
183 }
184
185 public void processText(final String text)
186 throws DataSourceException, ReportProcessingException
187 {
188 try
189 {
190 writer.writeText(XmlWriterSupport.normalize(text, false));
191 }
192 catch (IOException e)
193 {
194 throw new ReportProcessingException("IOError", e);
195 }
196 }
197
198
199 public void commit()
200 throws ReportProcessingException
201 {
202 try
203 {
204 writer.flush();
205 }
206 catch (IOException e)
207 {
208 throw new ReportProcessingException("Failed to flush", e);
209 }
210 }
211
212 public String getExportDescriptor()
213 {
214 return "raw/text+xml";
215 }
216
217 protected AttributeList buildAttributeList(final AttributeMap attrs)
218 {
219 final AttributeList attrList = new AttributeList();
220 final String[] namespaces = attrs.getNameSpaces();
221 for (int i = 0; i < namespaces.length; i++)
222 {
223 final String attrNamespace = namespaces[i];
224 if (isInternalNamespace(attrNamespace))
225 {
226 continue;
227 }
228
229 final Map localAttributes = attrs.getAttributes(attrNamespace);
230 final Iterator entries = localAttributes.entrySet().iterator();
231 while (entries.hasNext())
232 {
233 final Map.Entry entry = (Map.Entry) entries.next();
234 final String key = String.valueOf(entry.getKey());
235 validateNamespace(attrNamespace, attrList);
236 attrList.setAttribute(attrNamespace, key,
237 String.valueOf(entry.getValue()));
238 }
239 }
240 return attrList;
241 }
242
243 private void validateNamespace(final String uri, final AttributeList list)
244 {
245 if (writer.isNamespaceDefined(uri))
246 {
247 return;
248 }
249
250 if (list.isNamespaceUriDefined(uri))
251 {
252 return;
253 }
254
255 final NamespaceDefinition def = getNamespaceByUri(uri);
256 if (def != null)
257 {
258 final String prefix = def.getPreferredPrefix();
259 if (writer.isNamespacePrefixDefined(prefix) == false &&
260 list.isNamespacePrefixDefined(prefix) == false)
261 {
262 list.addNamespaceDeclaration (prefix, uri);
263 }
264 else
265 {
266 list.addNamespaceDeclaration
267 (namespacePrefixGenerator.generateName(prefix), uri);
268 }
269 }
270 else
271 {
272 list.addNamespaceDeclaration
273 (namespacePrefixGenerator.generateName("auto"), uri);
274 }
275 }
276
277 private boolean isInternalNamespace(final String namespace)
278 {
279 return JFreeReportInfo.REPORT_NAMESPACE.equals(namespace);
280 }
281
282 }