0001: /*
0002: * ============================================================================
0003: * GNU Lesser General Public License
0004: * ============================================================================
0005: *
0006: * JasperReports - Free Java report-generating library.
0007: * Copyright (C) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com
0008: *
0009: * This library is free software; you can redistribute it and/or
0010: * modify it under the terms of the GNU Lesser General Public
0011: * License as published by the Free Software Foundation; either
0012: * version 2.1 of the License, or (at your option) any later version.
0013: *
0014: * This library is distributed in the hope that it will be useful,
0015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0017: * Lesser General Public License for more details.
0018: *
0019: * You should have received a copy of the GNU Lesser General Public
0020: * License along with this library; if not, write to the Free Software
0021: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
0022: *
0023: * JasperSoft Corporation
0024: * 303 Second Street, Suite 450 North
0025: * San Francisco, CA 94107
0026: * http://www.jaspersoft.com
0027: */
0028:
0029: /*
0030: * Contributors:
0031: * Joakim Sandström - sanjoa@users.sourceforge.net
0032: */
0033: package net.sf.jasperreports.engine.export;
0034:
0035: import java.awt.Dimension;
0036: import java.io.BufferedWriter;
0037: import java.io.ByteArrayInputStream;
0038: import java.io.ByteArrayOutputStream;
0039: import java.io.File;
0040: import java.io.FileOutputStream;
0041: import java.io.IOException;
0042: import java.io.OutputStream;
0043: import java.io.OutputStreamWriter;
0044: import java.io.StringWriter;
0045: import java.io.Writer;
0046: import java.util.Collection;
0047: import java.util.HashMap;
0048: import java.util.Iterator;
0049: import java.util.List;
0050: import java.util.Map;
0051:
0052: import net.sf.jasperreports.engine.JRAbstractExporter;
0053: import net.sf.jasperreports.engine.JRAnchor;
0054: import net.sf.jasperreports.engine.JRBox;
0055: import net.sf.jasperreports.engine.JRElement;
0056: import net.sf.jasperreports.engine.JRException;
0057: import net.sf.jasperreports.engine.JRExporterParameter;
0058: import net.sf.jasperreports.engine.JRFont;
0059: import net.sf.jasperreports.engine.JRHyperlink;
0060: import net.sf.jasperreports.engine.JRImage;
0061: import net.sf.jasperreports.engine.JRImageRenderer;
0062: import net.sf.jasperreports.engine.JRLine;
0063: import net.sf.jasperreports.engine.JRPrintElement;
0064: import net.sf.jasperreports.engine.JRPrintEllipse;
0065: import net.sf.jasperreports.engine.JRPrintFrame;
0066: import net.sf.jasperreports.engine.JRPrintGraphicElement;
0067: import net.sf.jasperreports.engine.JRPrintHyperlink;
0068: import net.sf.jasperreports.engine.JRPrintHyperlinkParameter;
0069: import net.sf.jasperreports.engine.JRPrintHyperlinkParameters;
0070: import net.sf.jasperreports.engine.JRPrintImage;
0071: import net.sf.jasperreports.engine.JRPrintLine;
0072: import net.sf.jasperreports.engine.JRPrintPage;
0073: import net.sf.jasperreports.engine.JRPrintRectangle;
0074: import net.sf.jasperreports.engine.JRPrintText;
0075: import net.sf.jasperreports.engine.JRPropertiesHolder;
0076: import net.sf.jasperreports.engine.JRPropertiesMap;
0077: import net.sf.jasperreports.engine.JRRenderable;
0078: import net.sf.jasperreports.engine.JRReport;
0079: import net.sf.jasperreports.engine.JRReportFont;
0080: import net.sf.jasperreports.engine.JRRuntimeException;
0081: import net.sf.jasperreports.engine.JRStyle;
0082: import net.sf.jasperreports.engine.JRWrappingSvgRenderer;
0083: import net.sf.jasperreports.engine.util.JRValueStringUtils;
0084: import net.sf.jasperreports.engine.util.JRXmlWriteHelper;
0085: import net.sf.jasperreports.engine.xml.JRXmlConstants;
0086:
0087: import org.w3c.tools.codec.Base64Encoder;
0088:
0089: /**
0090: * Exports a JasperReports document to an XML file that contains the same data as a {@link net.sf.jasperreports.engine.JasperPrint}
0091: * object, but in XML format, instead of a serialized class. Such XML files can be parsed back into <tt>JasperPrint</tt>
0092: * object using the {@link net.sf.jasperreports.engine.xml.JRPrintXmlLoader} utility class. Their structure is validated
0093: * against an internal DTD file called jasperprint.dtd
0094: *
0095: * @author Teodor Danciu (teodord@users.sourceforge.net)
0096: * @version $Id: JRXmlExporter.java 1818 2007-08-22 13:46:00Z teodord $
0097: */
0098: public class JRXmlExporter extends JRAbstractExporter {
0099:
0100: /**
0101: *
0102: */
0103: protected static final String DEFAULT_XML_ENCODING = "UTF-8";
0104: protected static final String DEFAULT_OBJECT_TYPE = "java.lang.String";
0105: protected static final String HTML_FILES_SUFFIX = "_files";
0106: protected static final String IMAGE_PREFIX = "img_";
0107:
0108: /**
0109: *
0110: */
0111: protected JRXmlWriteHelper xmlWriter = null;
0112: protected String encoding = null;
0113:
0114: protected JRExportProgressMonitor progressMonitor = null;
0115: protected Map rendererToImagePathMap = null;
0116: protected Map imageNameToImageDataMap = null;
0117: protected Map fontsMap = new HashMap();
0118: protected Map stylesMap = new HashMap();
0119:
0120: /**
0121: *
0122: */
0123: protected String dtdLocation = null;
0124: protected boolean isEmbeddingImages = true;
0125: protected File destFile = null;
0126: protected File imagesDir = null;
0127:
0128: /**
0129: *
0130: */
0131: private static int imageId = 0;
0132:
0133: /**
0134: *
0135: */
0136: public void exportReport() throws JRException {
0137: progressMonitor = (JRExportProgressMonitor) parameters
0138: .get(JRExporterParameter.PROGRESS_MONITOR);
0139:
0140: /* */
0141: setOffset();
0142:
0143: try {
0144: /* */
0145: setExportContext();
0146:
0147: /* */
0148: setInput();
0149:
0150: /* */
0151: setPageRange();
0152:
0153: dtdLocation = (String) parameters
0154: .get(JRXmlExporterParameter.DTD_LOCATION);
0155: if (dtdLocation == null) {
0156: dtdLocation = JRXmlConstants.JASPERPRINT_SYSTEM_ID;
0157: }
0158:
0159: encoding = (String) parameters
0160: .get(JRExporterParameter.CHARACTER_ENCODING);
0161: if (encoding == null) {
0162: encoding = DEFAULT_XML_ENCODING;
0163: }
0164:
0165: StringBuffer sb = (StringBuffer) parameters
0166: .get(JRExporterParameter.OUTPUT_STRING_BUFFER);
0167: if (sb != null) {
0168: StringBuffer buffer = exportReportToBuffer();
0169: sb.append(buffer.toString());
0170: } else {
0171: Writer outWriter = (Writer) parameters
0172: .get(JRExporterParameter.OUTPUT_WRITER);
0173: if (outWriter != null) {
0174: try {
0175: exportReportToStream(outWriter);
0176: } catch (IOException e) {
0177: throw new JRException(
0178: "Error writing to writer : "
0179: + jasperPrint.getName(), e);
0180: }
0181: } else {
0182: OutputStream os = (OutputStream) parameters
0183: .get(JRExporterParameter.OUTPUT_STREAM);
0184: if (os != null) {
0185: try {
0186: exportReportToStream(new OutputStreamWriter(
0187: os, encoding));
0188: } catch (Exception e) {
0189: throw new JRException(
0190: "Error writing to OutputStream : "
0191: + jasperPrint.getName(), e);
0192: }
0193: } else {
0194: destFile = (File) parameters
0195: .get(JRExporterParameter.OUTPUT_FILE);
0196: if (destFile == null) {
0197: String fileName = (String) parameters
0198: .get(JRExporterParameter.OUTPUT_FILE_NAME);
0199: if (fileName != null) {
0200: destFile = new File(fileName);
0201: } else {
0202: throw new JRException(
0203: "No output specified for the exporter.");
0204: }
0205: }
0206:
0207: imagesDir = new File(destFile.getParent(),
0208: destFile.getName() + HTML_FILES_SUFFIX);
0209:
0210: Boolean isEmbeddingImagesParameter = (Boolean) parameters
0211: .get(JRXmlExporterParameter.IS_EMBEDDING_IMAGES);
0212: if (isEmbeddingImagesParameter == null) {
0213: isEmbeddingImagesParameter = Boolean.TRUE;
0214: }
0215: isEmbeddingImages = isEmbeddingImagesParameter
0216: .booleanValue();
0217:
0218: exportReportToFile();
0219: }
0220: }
0221: }
0222: } finally {
0223: resetExportContext();
0224: }
0225: }
0226:
0227: /**
0228: *
0229: */
0230: protected void exportReportToFile() throws JRException {
0231: //if (!isEmbeddingImages)
0232: {
0233: rendererToImagePathMap = new HashMap();
0234: imageNameToImageDataMap = new HashMap();
0235: }
0236:
0237: Writer writer = null;
0238: try {
0239: OutputStream fileOutputStream = new FileOutputStream(
0240: destFile);
0241: writer = new BufferedWriter(new OutputStreamWriter(
0242: fileOutputStream, encoding));
0243: exportReportToStream(writer);
0244: } catch (IOException e) {
0245: throw new JRException(
0246: "Error writing to file : " + destFile, e);
0247: } finally {
0248: if (writer != null) {
0249: try {
0250: writer.close();
0251: } catch (IOException e) {
0252: }
0253: }
0254: }
0255:
0256: if (!isEmbeddingImages) {
0257: Collection imageNames = imageNameToImageDataMap.keySet();
0258: if (imageNames != null && imageNames.size() > 0) {
0259: if (!imagesDir.exists()) {
0260: imagesDir.mkdir();
0261: }
0262:
0263: for (Iterator it = imageNames.iterator(); it.hasNext();) {
0264: String imageName = (String) it.next();
0265: byte[] imageData = (byte[]) imageNameToImageDataMap
0266: .get(imageName);
0267:
0268: File imageFile = new File(imagesDir, imageName);
0269:
0270: OutputStream fos = null;
0271: try {
0272: fos = new FileOutputStream(imageFile);
0273: fos.write(imageData, 0, imageData.length);
0274: } catch (IOException e) {
0275: throw new JRException(
0276: "Error writing to image file : "
0277: + imageFile, e);
0278: } finally {
0279: if (fos != null) {
0280: try {
0281: fos.close();
0282: } catch (IOException e) {
0283: }
0284: }
0285: }
0286: }
0287: }
0288: }
0289: }
0290:
0291: /**
0292: *
0293: */
0294: protected StringBuffer exportReportToBuffer() throws JRException {
0295: StringWriter buffer = new StringWriter();
0296: try {
0297: exportReportToStream(buffer);
0298: } catch (IOException e) {
0299: throw new JRException(
0300: "Error while exporting report to buffer", e);
0301: }
0302: return buffer.getBuffer();
0303: }
0304:
0305: protected void exportReportToStream(Writer writer)
0306: throws JRException, IOException {
0307: xmlWriter = new JRXmlWriteHelper(writer);
0308:
0309: xmlWriter.writeProlog(encoding);
0310: xmlWriter.writePublicDoctype(
0311: JRXmlConstants.ELEMENT_jasperPrint,
0312: JRXmlConstants.JASPERPRINT_PUBLIC_ID, dtdLocation);
0313:
0314: xmlWriter.startElement(JRXmlConstants.ELEMENT_jasperPrint);
0315: xmlWriter.addEncodedAttribute(JRXmlConstants.ATTRIBUTE_name,
0316: jasperPrint.getName());
0317: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_pageWidth,
0318: jasperPrint.getPageWidth());
0319: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_pageHeight,
0320: jasperPrint.getPageHeight());
0321: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_orientation,
0322: jasperPrint.getOrientation(), JRXmlConstants
0323: .getOrientationMap(),
0324: JRReport.ORIENTATION_PORTRAIT);
0325: xmlWriter.addAttribute(
0326: JRXmlConstants.ATTRIBUTE_formatFactoryClass,
0327: jasperPrint.getFormatFactoryClass());
0328: xmlWriter.addEncodedAttribute(JRXmlConstants.ATTRIBUTE_locale,
0329: jasperPrint.getLocaleCode());
0330: xmlWriter.addEncodedAttribute(
0331: JRXmlConstants.ATTRIBUTE_timezone, jasperPrint
0332: .getTimeZoneId());
0333:
0334: exportProperties(jasperPrint);
0335:
0336: JRReportFont[] fonts = jasperPrint.getFonts();
0337: if (fonts != null && fonts.length > 0) {
0338: for (int i = 0; i < fonts.length; i++) {
0339: fontsMap.put(fonts[i].getName(), fonts[i]);
0340: exportReportFont(fonts[i]);
0341: }
0342: }
0343:
0344: JRStyle[] styles = jasperPrint.getStyles();
0345: if (styles != null && styles.length > 0) {
0346: for (int i = 0; i < styles.length; i++) {
0347: stylesMap.put(styles[i].getName(), styles[i]);
0348: exportStyle(styles[i]);
0349: }
0350: }
0351:
0352: List pages = jasperPrint.getPages();
0353: if (pages != null && pages.size() > 0) {
0354: JRPrintPage page = null;
0355: for (int i = startPageIndex; i <= endPageIndex; i++) {
0356: if (Thread.currentThread().isInterrupted()) {
0357: throw new JRException("Current thread interrupted.");
0358: }
0359:
0360: page = (JRPrintPage) pages.get(i);
0361:
0362: /* */
0363: exportPage(page);
0364: }
0365: }
0366:
0367: xmlWriter.closeElement();
0368:
0369: writer.flush();
0370: }
0371:
0372: protected void exportProperties(JRPropertiesHolder propertiesHolder)
0373: throws IOException {
0374: JRPropertiesMap propertiesMap = propertiesHolder
0375: .getPropertiesMap();
0376: if (propertiesMap != null) {
0377: String[] propertyNames = propertiesMap.getPropertyNames();
0378: if (propertyNames != null && propertyNames.length > 0) {
0379: for (int i = 0; i < propertyNames.length; i++) {
0380: String value = propertiesMap
0381: .getProperty(propertyNames[i]);
0382: if (value != null) {
0383: xmlWriter
0384: .startElement(JRXmlConstants.ELEMENT_property);
0385: xmlWriter.addEncodedAttribute(
0386: JRXmlConstants.ATTRIBUTE_name,
0387: propertyNames[i]);
0388: xmlWriter.addEncodedAttribute(
0389: JRXmlConstants.ATTRIBUTE_value, value);
0390: xmlWriter.closeElement();
0391: }
0392: }
0393: }
0394: }
0395: }
0396:
0397: /**
0398: * @throws IOException
0399: *
0400: */
0401: protected void exportReportFont(JRReportFont font)
0402: throws IOException {
0403: xmlWriter.startElement(JRXmlConstants.ELEMENT_reportFont);
0404: xmlWriter.addEncodedAttribute(JRXmlConstants.ATTRIBUTE_name,
0405: font.getName());
0406: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_isDefault, font
0407: .isDefault());
0408: xmlWriter.addEncodedAttribute(
0409: JRXmlConstants.ATTRIBUTE_fontName, font.getFontName());
0410: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_size, font
0411: .getFontSize());
0412: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_isBold, font
0413: .isBold());
0414: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_isItalic, font
0415: .isItalic());
0416: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_isUnderline,
0417: font.isUnderline());
0418: xmlWriter.addAttribute(
0419: JRXmlConstants.ATTRIBUTE_isStrikeThrough, font
0420: .isStrikeThrough());
0421: xmlWriter.addEncodedAttribute(
0422: JRXmlConstants.ATTRIBUTE_pdfFontName, font
0423: .getPdfFontName());
0424: xmlWriter.addEncodedAttribute(
0425: JRXmlConstants.ATTRIBUTE_pdfEncoding, font
0426: .getPdfEncoding());
0427: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_isPdfEmbedded,
0428: font.isPdfEmbedded());
0429: xmlWriter.closeElement();
0430: }
0431:
0432: /**
0433: * @throws IOException
0434: */
0435: protected void exportStyle(JRStyle style) throws IOException {
0436: xmlWriter.startElement(JRXmlConstants.ELEMENT_style);
0437: xmlWriter.addEncodedAttribute(JRXmlConstants.ATTRIBUTE_name,
0438: style.getName());
0439: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_isDefault,
0440: style.isDefault());
0441:
0442: if (style.getStyle() != null) {
0443: JRStyle baseStyle = (JRStyle) stylesMap.get(style
0444: .getStyle().getName());
0445: if (baseStyle != null) {
0446: xmlWriter.addEncodedAttribute(
0447: JRXmlConstants.ATTRIBUTE_style, style
0448: .getStyle().getName());
0449: } else {
0450: throw new JRRuntimeException(
0451: "Referenced report style not found : "
0452: + style.getStyle().getName());
0453: }
0454: }
0455:
0456: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_mode, style
0457: .getOwnMode(), JRXmlConstants.getModeMap());
0458: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_forecolor,
0459: style.getOwnForecolor());
0460: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_backcolor,
0461: style.getOwnBackcolor());
0462: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_pen, style
0463: .getOwnPen(), JRXmlConstants.getPenMap());
0464: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_fill, style
0465: .getOwnFill(), JRXmlConstants.getFillMap());
0466: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_radius, style
0467: .getOwnRadius());
0468: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_scaleImage,
0469: style.getOwnScaleImage(), JRXmlConstants
0470: .getScaleImageMap());
0471: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_hAlign, style
0472: .getOwnHorizontalAlignment(), JRXmlConstants
0473: .getHorizontalAlignMap());
0474: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_vAlign, style
0475: .getOwnVerticalAlignment(), JRXmlConstants
0476: .getVerticalAlignMap());
0477: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_rotation, style
0478: .getOwnRotation(), JRXmlConstants.getRotationMap());
0479: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_lineSpacing,
0480: style.getOwnLineSpacing(), JRXmlConstants
0481: .getLineSpacingMap());
0482: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_isStyledText,
0483: style.isOwnStyledText());
0484: //xmlWriter.addEncodedAttribute(JRXmlConstants.ATTRIBUTE_pattern, style.getOwnPattern());//FIXME if pattern in text field is equal to this, then it should be removed there (inheritance)
0485: //xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_isBlankWhenNull, style.isOwnBlankWhenNull());
0486:
0487: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_border, style
0488: .getOwnBorder(), JRXmlConstants.getPenMap());
0489: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_borderColor,
0490: style.getOwnBorderColor());
0491: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_padding, style
0492: .getOwnPadding());
0493:
0494: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_topBorder,
0495: style.getOwnTopBorder(), JRXmlConstants.getPenMap());
0496: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_topBorderColor,
0497: style.getOwnTopBorderColor());
0498: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_topPadding,
0499: style.getOwnTopPadding());
0500:
0501: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_leftBorder,
0502: style.getOwnLeftBorder(), JRXmlConstants.getPenMap());
0503: xmlWriter.addAttribute(
0504: JRXmlConstants.ATTRIBUTE_leftBorderColor, style
0505: .getOwnLeftBorderColor());
0506: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_leftPadding,
0507: style.getOwnLeftPadding());
0508:
0509: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_bottomBorder,
0510: style.getOwnBottomBorder(), JRXmlConstants.getPenMap());
0511: xmlWriter.addAttribute(
0512: JRXmlConstants.ATTRIBUTE_bottomBorderColor, style
0513: .getOwnBottomBorderColor());
0514: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_bottomPadding,
0515: style.getOwnBottomPadding());
0516:
0517: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_rightBorder,
0518: style.getOwnRightBorder(), JRXmlConstants.getPenMap());
0519: xmlWriter.addAttribute(
0520: JRXmlConstants.ATTRIBUTE_rightBorderColor, style
0521: .getOwnRightBorderColor());
0522: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_rightPadding,
0523: style.getOwnRightPadding());
0524:
0525: xmlWriter.addEncodedAttribute(
0526: JRXmlConstants.ATTRIBUTE_fontName, style
0527: .getOwnFontName());
0528: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_fontSize, style
0529: .getOwnFontSize());
0530: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_isBold, style
0531: .isOwnBold());
0532: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_isItalic, style
0533: .isOwnItalic());
0534: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_isUnderline,
0535: style.isOwnUnderline());
0536: xmlWriter.addAttribute(
0537: JRXmlConstants.ATTRIBUTE_isStrikeThrough, style
0538: .isOwnStrikeThrough());
0539: xmlWriter.addEncodedAttribute(
0540: JRXmlConstants.ATTRIBUTE_pdfFontName, style
0541: .getOwnPdfFontName());
0542: xmlWriter.addEncodedAttribute(
0543: JRXmlConstants.ATTRIBUTE_pdfEncoding, style
0544: .getOwnPdfEncoding());
0545: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_isPdfEmbedded,
0546: style.isOwnPdfEmbedded());
0547:
0548: xmlWriter.closeElement();
0549: }
0550:
0551: /**
0552: * @throws IOException
0553: *
0554: */
0555: protected void exportPage(JRPrintPage page) throws JRException,
0556: IOException {
0557: xmlWriter.startElement(JRXmlConstants.ELEMENT_page);
0558:
0559: Collection elements = page.getElements();
0560: exportElements(elements);
0561:
0562: xmlWriter.closeElement();
0563:
0564: if (progressMonitor != null) {
0565: progressMonitor.afterPageExport();
0566: }
0567: }
0568:
0569: protected void exportElements(Collection elements)
0570: throws IOException, JRException {
0571: if (elements != null && elements.size() > 0) {
0572: JRPrintElement element;
0573: for (Iterator it = elements.iterator(); it.hasNext();) {
0574: element = (JRPrintElement) it.next();
0575:
0576: if (element instanceof JRPrintLine) {
0577: exportLine((JRPrintLine) element);
0578: } else if (element instanceof JRPrintRectangle) {
0579: exportRectangle((JRPrintRectangle) element);
0580: } else if (element instanceof JRPrintEllipse) {
0581: exportEllipse((JRPrintEllipse) element);
0582: } else if (element instanceof JRPrintImage) {
0583: exportImage((JRPrintImage) element);
0584: } else if (element instanceof JRPrintText) {
0585: exportText((JRPrintText) element);
0586: } else if (element instanceof JRPrintFrame) {
0587: exportFrame((JRPrintFrame) element);
0588: }
0589: }
0590: }
0591: }
0592:
0593: /**
0594: * @throws IOException
0595: *
0596: */
0597: protected void exportLine(JRPrintLine line) throws IOException {
0598: xmlWriter.startElement(JRXmlConstants.ELEMENT_line);
0599: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_direction, line
0600: .getDirection(), JRXmlConstants.getDirectionMap(),
0601: JRLine.DIRECTION_TOP_DOWN);
0602:
0603: exportReportElement(line);
0604: exportGraphicElement(line);
0605:
0606: xmlWriter.closeElement();
0607: }
0608:
0609: /**
0610: * @throws IOException
0611: *
0612: */
0613: protected void exportReportElement(JRPrintElement element)
0614: throws IOException {
0615: xmlWriter.startElement(JRXmlConstants.ELEMENT_reportElement);
0616: xmlWriter.addEncodedAttribute(JRXmlConstants.ATTRIBUTE_key,
0617: element.getKey());
0618: JRStyle style = element.getStyle();
0619: if (style != null) {
0620: xmlWriter.addEncodedAttribute(
0621: JRXmlConstants.ATTRIBUTE_style, style.getName());
0622: }
0623: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_mode, element
0624: .getOwnMode(), JRXmlConstants.getModeMap());
0625: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_x, element
0626: .getX()
0627: + getOffsetX());
0628: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_y, element
0629: .getY()
0630: + getOffsetY());
0631: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_width, element
0632: .getWidth());
0633: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_height, element
0634: .getHeight());
0635: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_forecolor,
0636: element.getOwnForecolor());
0637: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_backcolor,
0638: element.getOwnBackcolor());
0639: xmlWriter.closeElement();
0640: }
0641:
0642: /**
0643: * @throws IOException
0644: *
0645: */
0646: protected void exportGraphicElement(JRPrintGraphicElement element)
0647: throws IOException {
0648: xmlWriter.startElement(JRXmlConstants.ELEMENT_graphicElement);
0649: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_pen, element
0650: .getOwnPen(), JRXmlConstants.getPenMap());
0651: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_fill, element
0652: .getOwnFill(), JRXmlConstants.getFillMap());
0653: xmlWriter.closeElement();
0654: }
0655:
0656: /**
0657: * @throws IOException
0658: *
0659: */
0660: protected void exportRectangle(JRPrintRectangle rectangle)
0661: throws IOException {
0662: xmlWriter.startElement(JRXmlConstants.ELEMENT_rectangle);
0663: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_radius,
0664: rectangle.getOwnRadius());
0665:
0666: exportReportElement(rectangle);
0667: exportGraphicElement(rectangle);
0668:
0669: xmlWriter.closeElement();
0670: }
0671:
0672: /**
0673: * @throws IOException
0674: *
0675: */
0676: protected void exportEllipse(JRPrintEllipse ellipse)
0677: throws IOException {
0678: xmlWriter.startElement(JRXmlConstants.ELEMENT_ellipse);
0679:
0680: exportReportElement(ellipse);
0681: exportGraphicElement(ellipse);
0682:
0683: xmlWriter.closeElement();
0684: }
0685:
0686: /**
0687: * @throws JRException
0688: * @throws IOException
0689: *
0690: */
0691: protected void exportImage(JRPrintImage image) throws JRException,
0692: IOException {
0693: xmlWriter.startElement(JRXmlConstants.ELEMENT_image);
0694: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_scaleImage,
0695: image.getOwnScaleImage(), JRXmlConstants
0696: .getScaleImageMap());
0697: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_hAlign, image
0698: .getOwnHorizontalAlignment(), JRXmlConstants
0699: .getHorizontalAlignMap());
0700: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_vAlign, image
0701: .getOwnVerticalAlignment(), JRXmlConstants
0702: .getVerticalAlignMap());
0703: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_isLazy, image
0704: .isLazy(), false);
0705: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_onErrorType,
0706: image.getOnErrorType(), JRXmlConstants
0707: .getOnErrorTypeMap(),
0708: JRImage.ON_ERROR_TYPE_ERROR);
0709: xmlWriter.addEncodedAttribute(
0710: JRXmlConstants.ATTRIBUTE_hyperlinkType, image
0711: .getLinkType());
0712: xmlWriter.addAttribute(
0713: JRXmlConstants.ATTRIBUTE_hyperlinkTarget, image
0714: .getHyperlinkTarget(), JRXmlConstants
0715: .getHyperlinkTargetMap(),
0716: JRHyperlink.HYPERLINK_TARGET_SELF);
0717: xmlWriter.addEncodedAttribute(
0718: JRXmlConstants.ATTRIBUTE_anchorName, image
0719: .getAnchorName());
0720: xmlWriter.addEncodedAttribute(
0721: JRXmlConstants.ATTRIBUTE_hyperlinkReference, image
0722: .getHyperlinkReference());
0723: xmlWriter.addEncodedAttribute(
0724: JRXmlConstants.ATTRIBUTE_hyperlinkAnchor, image
0725: .getHyperlinkAnchor());
0726: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_hyperlinkPage,
0727: image.getHyperlinkPage());
0728: xmlWriter.addEncodedAttribute(
0729: JRXmlConstants.ATTRIBUTE_hyperlinkTooltip, image
0730: .getHyperlinkTooltip());
0731: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_bookmarkLevel,
0732: image.getBookmarkLevel(), JRAnchor.NO_BOOKMARK);
0733:
0734: exportReportElement(image);
0735: exportBox(image);
0736: exportGraphicElement(image);
0737:
0738: JRRenderable renderer = image.getRenderer();
0739: if (renderer != null) {
0740: xmlWriter.startElement(JRXmlConstants.ELEMENT_imageSource);
0741: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_isEmbedded,
0742: isEmbeddingImages && !image.isLazy(), false);
0743:
0744: String imageSource = "";
0745:
0746: if (renderer.getType() == JRRenderable.TYPE_SVG) {
0747: renderer = new JRWrappingSvgRenderer(
0748: renderer,
0749: new Dimension(image.getWidth(), image
0750: .getHeight()),
0751: JRElement.MODE_OPAQUE == image.getMode() ? image
0752: .getBackcolor()
0753: : null);
0754: }
0755:
0756: if (isEmbeddingImages && !image.isLazy()) {
0757: try {
0758: ByteArrayInputStream bais = new ByteArrayInputStream(
0759: renderer.getImageData());
0760: ByteArrayOutputStream baos = new ByteArrayOutputStream();
0761:
0762: Base64Encoder encoder = new Base64Encoder(bais,
0763: baos);
0764: encoder.process();
0765:
0766: imageSource = new String(baos.toByteArray(),
0767: DEFAULT_XML_ENCODING);
0768: } catch (IOException e) {
0769: throw new JRException(
0770: "Error embedding image into XML.", e);
0771: }
0772: } else {
0773: if (renderer.getType() == JRRenderable.TYPE_IMAGE
0774: && rendererToImagePathMap.containsKey(renderer)) {
0775: imageSource = (String) rendererToImagePathMap
0776: .get(renderer);
0777: } else {
0778: if (image.isLazy()) {
0779: imageSource = ((JRImageRenderer) renderer)
0780: .getImageLocation();
0781: } else {
0782: imageSource = IMAGE_PREFIX + getNextImageId();
0783: imageNameToImageDataMap.put(imageSource,
0784: renderer.getImageData());
0785:
0786: imageSource = new File(imagesDir, imageSource)
0787: .getPath();
0788: }
0789:
0790: rendererToImagePathMap.put(renderer, imageSource);
0791: }
0792: }
0793:
0794: xmlWriter.writeCDATA(imageSource);
0795: xmlWriter.closeElement();
0796: }
0797:
0798: exportHyperlinkParameters(image);
0799:
0800: xmlWriter.closeElement();
0801: }
0802:
0803: /**
0804: * @throws IOException
0805: *
0806: */
0807: protected void exportText(JRPrintText text) throws IOException {
0808: xmlWriter.startElement(JRXmlConstants.ELEMENT_text);
0809: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_textAlignment,
0810: text.getOwnHorizontalAlignment(), JRXmlConstants
0811: .getHorizontalAlignMap());
0812: xmlWriter.addAttribute(
0813: JRXmlConstants.ATTRIBUTE_verticalAlignment, text
0814: .getOwnVerticalAlignment(), JRXmlConstants
0815: .getVerticalAlignMap());
0816: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_textHeight,
0817: text.getTextHeight());
0818: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_rotation, text
0819: .getOwnRotation(), JRXmlConstants.getRotationMap());
0820: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_runDirection,
0821: text.getRunDirection(), JRXmlConstants
0822: .getRunDirectionMap(),
0823: JRPrintText.RUN_DIRECTION_LTR);
0824: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_lineSpacing,
0825: text.getOwnLineSpacing(), JRXmlConstants
0826: .getLineSpacingMap());
0827: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_isStyledText,
0828: text.isOwnStyledText());
0829: xmlWriter.addAttribute(
0830: JRXmlConstants.ATTRIBUTE_lineSpacingFactor, text
0831: .getLineSpacingFactor());
0832: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_leadingOffset,
0833: text.getLeadingOffset());
0834: xmlWriter.addEncodedAttribute(
0835: JRXmlConstants.ATTRIBUTE_hyperlinkType, text
0836: .getLinkType());
0837: xmlWriter.addAttribute(
0838: JRXmlConstants.ATTRIBUTE_hyperlinkTarget, text
0839: .getHyperlinkTarget(), JRXmlConstants
0840: .getHyperlinkTargetMap(),
0841: JRHyperlink.HYPERLINK_TARGET_SELF);
0842: xmlWriter.addEncodedAttribute(
0843: JRXmlConstants.ATTRIBUTE_anchorName, text
0844: .getAnchorName());
0845: xmlWriter.addEncodedAttribute(
0846: JRXmlConstants.ATTRIBUTE_hyperlinkReference, text
0847: .getHyperlinkReference());
0848: xmlWriter.addEncodedAttribute(
0849: JRXmlConstants.ATTRIBUTE_hyperlinkAnchor, text
0850: .getHyperlinkAnchor());
0851: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_hyperlinkPage,
0852: text.getHyperlinkPage());
0853: xmlWriter.addEncodedAttribute(
0854: JRXmlConstants.ATTRIBUTE_hyperlinkTooltip, text
0855: .getHyperlinkTooltip());
0856: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_bookmarkLevel,
0857: text.getBookmarkLevel(), JRAnchor.NO_BOOKMARK);
0858: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_valueClass,
0859: text.getValueClassName());
0860: xmlWriter.addEncodedAttribute(JRXmlConstants.ATTRIBUTE_pattern,
0861: text.getPattern());
0862: xmlWriter.addAttribute(
0863: JRXmlConstants.ATTRIBUTE_formatFactoryClass, text
0864: .getFormatFactoryClass());
0865: xmlWriter.addEncodedAttribute(JRXmlConstants.ATTRIBUTE_locale,
0866: text.getLocaleCode());
0867: xmlWriter
0868: .addEncodedAttribute(JRXmlConstants.ATTRIBUTE_timezone,
0869: text.getTimeZoneId());
0870:
0871: exportReportElement(text);
0872: exportBox(text);
0873:
0874: exportFont(text);
0875:
0876: if (text.getText() != null) {
0877: xmlWriter.writeCDATAElement(
0878: JRXmlConstants.ELEMENT_textContent, text.getText());
0879: }
0880:
0881: exportHyperlinkParameters(text);
0882:
0883: xmlWriter.closeElement();
0884: }
0885:
0886: /**
0887: * @throws IOException
0888: *
0889: */
0890: private void exportBox(JRBox box) throws IOException {
0891: if (box != null) {
0892: xmlWriter.startElement(JRXmlConstants.ELEMENT_box);
0893:
0894: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_border, box
0895: .getOwnBorder(), JRXmlConstants.getPenMap());
0896: xmlWriter.addAttribute(
0897: JRXmlConstants.ATTRIBUTE_borderColor, box
0898: .getOwnBorderColor());
0899: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_padding,
0900: box.getOwnPadding());
0901:
0902: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_topBorder,
0903: box.getOwnTopBorder(), JRXmlConstants.getPenMap());
0904: xmlWriter.addAttribute(
0905: JRXmlConstants.ATTRIBUTE_topBorderColor, box
0906: .getOwnTopBorderColor());
0907: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_topPadding,
0908: box.getOwnTopPadding());
0909:
0910: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_leftBorder,
0911: box.getOwnLeftBorder(), JRXmlConstants.getPenMap());
0912: xmlWriter.addAttribute(
0913: JRXmlConstants.ATTRIBUTE_leftBorderColor, box
0914: .getOwnLeftBorderColor());
0915: xmlWriter.addAttribute(
0916: JRXmlConstants.ATTRIBUTE_leftPadding, box
0917: .getOwnLeftPadding());
0918:
0919: xmlWriter.addAttribute(
0920: JRXmlConstants.ATTRIBUTE_bottomBorder, box
0921: .getOwnBottomBorder(), JRXmlConstants
0922: .getPenMap());
0923: xmlWriter.addAttribute(
0924: JRXmlConstants.ATTRIBUTE_bottomBorderColor, box
0925: .getOwnBottomBorderColor());
0926: xmlWriter.addAttribute(
0927: JRXmlConstants.ATTRIBUTE_bottomPadding, box
0928: .getOwnBottomPadding());
0929:
0930: xmlWriter.addAttribute(
0931: JRXmlConstants.ATTRIBUTE_rightBorder, box
0932: .getOwnRightBorder(), JRXmlConstants
0933: .getPenMap());
0934: xmlWriter.addAttribute(
0935: JRXmlConstants.ATTRIBUTE_rightBorderColor, box
0936: .getOwnRightBorderColor());
0937: xmlWriter.addAttribute(
0938: JRXmlConstants.ATTRIBUTE_rightPadding, box
0939: .getOwnRightPadding());
0940:
0941: xmlWriter.closeElement(true);
0942: }
0943: }
0944:
0945: /**
0946: *
0947: */
0948: protected void exportFont(JRFont font) throws IOException {
0949: if (font != null) {
0950: xmlWriter.startElement(JRXmlConstants.ELEMENT_font);
0951:
0952: if (font.getReportFont() != null) {
0953: JRFont baseFont = (JRFont) fontsMap.get(font
0954: .getReportFont().getName());
0955: if (baseFont != null) {
0956: xmlWriter.addEncodedAttribute(
0957: JRXmlConstants.ATTRIBUTE_reportFont, font
0958: .getReportFont().getName());
0959: } else {
0960: throw new JRRuntimeException(
0961: "Referenced report font not found : "
0962: + font.getReportFont().getName());
0963: }
0964: }
0965:
0966: xmlWriter.addEncodedAttribute(
0967: JRXmlConstants.ATTRIBUTE_fontName, font
0968: .getOwnFontName());
0969: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_size, font
0970: .getOwnFontSize());
0971: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_isBold,
0972: font.isOwnBold());
0973: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_isItalic,
0974: font.isOwnItalic());
0975: xmlWriter.addAttribute(
0976: JRXmlConstants.ATTRIBUTE_isUnderline, font
0977: .isOwnUnderline());
0978: xmlWriter.addAttribute(
0979: JRXmlConstants.ATTRIBUTE_isStrikeThrough, font
0980: .isOwnStrikeThrough());
0981: xmlWriter.addEncodedAttribute(
0982: JRXmlConstants.ATTRIBUTE_pdfFontName, font
0983: .getOwnPdfFontName());
0984: xmlWriter.addEncodedAttribute(
0985: JRXmlConstants.ATTRIBUTE_pdfEncoding, font
0986: .getOwnPdfEncoding());
0987: xmlWriter.addAttribute(
0988: JRXmlConstants.ATTRIBUTE_isPdfEmbedded, font
0989: .isOwnPdfEmbedded());
0990: xmlWriter.closeElement(true);
0991: }
0992: }
0993:
0994: protected void exportFrame(JRPrintFrame frame) throws IOException,
0995: JRException {
0996: xmlWriter.startElement(JRXmlConstants.ELEMENT_frame);
0997:
0998: setFrameElementsOffset(frame, true);
0999: try {
1000: exportReportElement(frame);
1001: exportBox(frame);
1002: exportElements(frame.getElements());
1003:
1004: xmlWriter.closeElement();
1005: } finally {
1006: restoreElementOffsets();
1007: }
1008: }
1009:
1010: /**
1011: *
1012: */
1013: private static synchronized int getNextImageId() {
1014: return imageId++;
1015: }
1016:
1017: protected void exportHyperlinkParameters(JRPrintHyperlink hyperlink)
1018: throws IOException {
1019: JRPrintHyperlinkParameters hyperlinkParameters = hyperlink
1020: .getHyperlinkParameters();
1021: if (hyperlinkParameters != null) {
1022: for (Iterator it = hyperlinkParameters.getParameters()
1023: .iterator(); it.hasNext();) {
1024: JRPrintHyperlinkParameter parameter = (JRPrintHyperlinkParameter) it
1025: .next();
1026: exportHyperlinkParameter(parameter);
1027: }
1028: }
1029: }
1030:
1031: protected void exportHyperlinkParameter(
1032: JRPrintHyperlinkParameter parameter) throws IOException {
1033: xmlWriter
1034: .startElement(JRXmlConstants.ELEMENT_hyperlinkParameter);
1035: xmlWriter.addEncodedAttribute(JRXmlConstants.ATTRIBUTE_name,
1036: parameter.getName());
1037: xmlWriter.addAttribute(JRXmlConstants.ATTRIBUTE_class,
1038: parameter.getValueClass(), DEFAULT_OBJECT_TYPE);
1039:
1040: if (parameter.getValue() != null) {
1041: String data = JRValueStringUtils.serialize(parameter
1042: .getValueClass(), parameter.getValue());
1043: xmlWriter.writeCDATAElement(
1044: JRXmlConstants.ELEMENT_hyperlinkParameterValue,
1045: data);
1046: }
1047:
1048: xmlWriter.closeElement();
1049: }
1050: }
|