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 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 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 final 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 }