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: * Special thanks to Google 'Summer of Code 2005' program for supporting this development
0031: *
0032: * Contributors:
0033: * Majid Ali Khan - majidkk@users.sourceforge.net
0034: * Frank Schönheit - Frank.Schoenheit@Sun.COM
0035: */
0036: package net.sf.jasperreports.engine.export.oasis;
0037:
0038: import java.awt.Color;
0039: import java.io.File;
0040: import java.io.FileOutputStream;
0041: import java.io.IOException;
0042: import java.io.OutputStream;
0043: import java.io.Writer;
0044: import java.text.AttributedCharacterIterator;
0045: import java.util.ArrayList;
0046: import java.util.Collection;
0047: import java.util.HashMap;
0048: import java.util.Iterator;
0049: import java.util.LinkedList;
0050: import java.util.List;
0051: import java.util.Map;
0052:
0053: import net.sf.jasperreports.engine.JRAbstractExporter;
0054: import net.sf.jasperreports.engine.JRException;
0055: import net.sf.jasperreports.engine.JRExporterParameter;
0056: import net.sf.jasperreports.engine.JRPrintElement;
0057: import net.sf.jasperreports.engine.JRPrintEllipse;
0058: import net.sf.jasperreports.engine.JRPrintFrame;
0059: import net.sf.jasperreports.engine.JRPrintImage;
0060: import net.sf.jasperreports.engine.JRPrintLine;
0061: import net.sf.jasperreports.engine.JRPrintPage;
0062: import net.sf.jasperreports.engine.JRPrintRectangle;
0063: import net.sf.jasperreports.engine.JRPrintText;
0064: import net.sf.jasperreports.engine.JasperPrint;
0065: import net.sf.jasperreports.engine.export.JRExportProgressMonitor;
0066: import net.sf.jasperreports.engine.export.JRHyperlinkProducerFactory;
0067: import net.sf.jasperreports.engine.export.oasis.zip.FileBufferedOasisZip;
0068: import net.sf.jasperreports.engine.export.oasis.zip.FileBufferedOasisZipEntry;
0069: import net.sf.jasperreports.engine.export.oasis.zip.OasisZip;
0070: import net.sf.jasperreports.engine.export.oasis.zip.OasisZipEntry;
0071: import net.sf.jasperreports.engine.util.JRStringUtil;
0072: import net.sf.jasperreports.engine.util.JRStyledText;
0073:
0074: /**
0075: * Exports a JasperReports document to ODF format. It has character output type and exports the document to a
0076: * grid-based layout.
0077: * @author Teodor Danciu (teodord@users.sourceforge.net)
0078: * @version $Id: JROdtFrameExporter.java 1745 2007-06-11 15:13:18Z teodord $
0079: */
0080: public class JROdtFrameExporter extends JRAbstractExporter {
0081:
0082: /**
0083: *
0084: */
0085: public static final String VERSION = "1.0";
0086:
0087: /**
0088: *
0089: */
0090: protected static final String JR_PAGE_ANCHOR_PREFIX = "JR_PAGE_ANCHOR_";
0091:
0092: public static final String IMAGE_NAME_PREFIX = "img_";
0093: protected static final int IMAGE_NAME_PREFIX_LEGTH = IMAGE_NAME_PREFIX
0094: .length();
0095:
0096: /**
0097: *
0098: */
0099: protected Writer tempBodyWriter = null;
0100: protected Writer tempStyleWriter = null;
0101:
0102: protected JRExportProgressMonitor progressMonitor = null;
0103: protected Map rendererToImagePathMap = null;
0104: protected Map imageMaps;
0105: protected List imagesToProcess = null;
0106:
0107: protected int reportIndex = 0;
0108: protected int pageIndex = 0;
0109: protected int tableIndex = 0;
0110:
0111: /**
0112: *
0113: */
0114: protected String encoding = null;
0115:
0116: /**
0117: *
0118: */
0119: protected boolean isWrapBreakWord = false;
0120:
0121: protected Map fontMap = null;
0122:
0123: private LinkedList backcolorStack;
0124: private Color backcolor;
0125:
0126: private StyleCache styleCache = null;
0127:
0128: protected JRHyperlinkProducerFactory hyperlinkProducerFactory;
0129:
0130: public JROdtFrameExporter() {
0131: backcolorStack = new LinkedList();
0132: backcolor = null;
0133: }
0134:
0135: /**
0136: *
0137: */
0138: public void exportReport() throws JRException {
0139: progressMonitor = (JRExportProgressMonitor) parameters
0140: .get(JRExporterParameter.PROGRESS_MONITOR);
0141:
0142: /* */
0143: setOffset();
0144:
0145: try {
0146: /* */
0147: setExportContext();
0148:
0149: /* */
0150: setInput();
0151:
0152: /* */
0153: if (!isModeBatch) {
0154: setPageRange();
0155: }
0156:
0157: encoding = (String) parameters
0158: .get(JRExporterParameter.CHARACTER_ENCODING);
0159: if (encoding == null) {
0160: encoding = "UTF-8";
0161: }
0162:
0163: rendererToImagePathMap = new HashMap();
0164: imageMaps = new HashMap();
0165: imagesToProcess = new ArrayList();
0166:
0167: fontMap = (Map) parameters
0168: .get(JRExporterParameter.FONT_MAP);
0169:
0170: setHyperlinkProducerFactory();
0171:
0172: OutputStream os = (OutputStream) parameters
0173: .get(JRExporterParameter.OUTPUT_STREAM);
0174: if (os != null) {
0175: try {
0176: exportReportToOasisZip(os);
0177: } catch (IOException e) {
0178: throw new JRException(
0179: "Error trying to export to output stream : "
0180: + jasperPrint.getName(), e);
0181: }
0182: } else {
0183: File destFile = (File) parameters
0184: .get(JRExporterParameter.OUTPUT_FILE);
0185: if (destFile == null) {
0186: String fileName = (String) parameters
0187: .get(JRExporterParameter.OUTPUT_FILE_NAME);
0188: if (fileName != null) {
0189: destFile = new File(fileName);
0190: } else {
0191: throw new JRException(
0192: "No output specified for the exporter.");
0193: }
0194: }
0195:
0196: try {
0197: os = new FileOutputStream(destFile);
0198: exportReportToOasisZip(os);
0199: } catch (IOException e) {
0200: throw new JRException(
0201: "Error trying to export to file : "
0202: + destFile, e);
0203: } finally {
0204: if (os != null) {
0205: try {
0206: os.close();
0207: } catch (IOException e) {
0208: }
0209: }
0210: }
0211: }
0212: } finally {
0213: resetExportContext();
0214: }
0215: }
0216:
0217: protected void setHyperlinkProducerFactory() {
0218: hyperlinkProducerFactory = (JRHyperlinkProducerFactory) parameters
0219: .get(JRExporterParameter.HYPERLINK_PRODUCER_FACTORY);
0220: }
0221:
0222: /**
0223: *
0224: *
0225: public static JRPrintImage getImage(List jasperPrintList, String imageName)
0226: {
0227: return getImage(jasperPrintList, getPrintElementIndex(imageName));
0228: }
0229:
0230:
0231: public static JRPrintImage getImage(List jasperPrintList, JRPrintElementIndex imageIndex)
0232: {
0233: JasperPrint report = (JasperPrint)jasperPrintList.get(imageIndex.getReportIndex());
0234: JRPrintPage page = (JRPrintPage)report.getPages().get(imageIndex.getPageIndex());
0235:
0236: Integer[] elementIndexes = imageIndex.getElementIndexes();
0237: Object element = page.getElements().get(elementIndexes[0].intValue());
0238:
0239: for (int i = 1; i < elementIndexes.length; ++i)
0240: {
0241: JRPrintFrame frame = (JRPrintFrame) element;
0242: element = frame.getElements().get(elementIndexes[i].intValue());
0243: }
0244:
0245: return (JRPrintImage) element;
0246: }
0247:
0248:
0249: /**
0250: *
0251: */
0252: protected void exportReportToOasisZip(OutputStream os)
0253: throws JRException, IOException {
0254: OasisZip oasisZip = new FileBufferedOasisZip();
0255:
0256: OasisZipEntry tempBodyEntry = new FileBufferedOasisZipEntry(
0257: null);
0258: OasisZipEntry tempStyleEntry = new FileBufferedOasisZipEntry(
0259: null);
0260:
0261: tempBodyWriter = tempBodyEntry.getWriter();
0262: tempStyleWriter = tempStyleEntry.getWriter();
0263:
0264: styleCache = new StyleCache(tempStyleWriter, fontMap);
0265:
0266: Writer stylesWriter = oasisZip.getStylesEntry().getWriter();
0267:
0268: StyleBuilder styleBuilder = new StyleBuilder(jasperPrintList,
0269: stylesWriter);
0270: styleBuilder.build();
0271:
0272: stylesWriter.close();
0273:
0274: for (reportIndex = 0; reportIndex < jasperPrintList.size(); reportIndex++) {
0275: jasperPrint = (JasperPrint) jasperPrintList
0276: .get(reportIndex);
0277:
0278: List pages = jasperPrint.getPages();
0279: if (pages != null && pages.size() > 0) {
0280: if (isModeBatch) {
0281: startPageIndex = 0;
0282: endPageIndex = pages.size() - 1;
0283: }
0284:
0285: JRPrintPage page = null;
0286: for (pageIndex = startPageIndex; pageIndex <= endPageIndex; pageIndex++) {
0287: if (Thread.currentThread().isInterrupted()) {
0288: throw new JRException(
0289: "Current thread interrupted.");
0290: }
0291:
0292: page = (JRPrintPage) pages.get(pageIndex);
0293:
0294: exportPage(page);
0295: }
0296: }
0297: }
0298:
0299: tempBodyWriter.flush();
0300: tempStyleWriter.flush();
0301:
0302: tempBodyWriter.close();
0303: tempStyleWriter.close();
0304:
0305: /* */
0306: ContentBuilder contentBuilder = new ContentBuilder(oasisZip
0307: .getContentEntry(), tempStyleEntry, tempBodyEntry,
0308: styleCache.getFontFaces());
0309: contentBuilder.build();
0310:
0311: oasisZip.zipEntries(os);
0312:
0313: oasisZip.dispose();
0314: }
0315:
0316: /**
0317: *
0318: */
0319: protected void exportPage(JRPrintPage page) throws JRException,
0320: IOException {
0321: //tempBodyWriter.write("<text:p text:style-name=\"PAGE_BREAK\"></text:p>");
0322:
0323: Collection elements = page.getElements();
0324: exportElements(elements);
0325:
0326: if (progressMonitor != null) {
0327: progressMonitor.afterPageExport();
0328: }
0329: }
0330:
0331: protected void exportElements(Collection elements)
0332: throws IOException, JRException {
0333: if (elements != null && elements.size() > 0) {
0334: JRPrintElement element;
0335: for (Iterator it = elements.iterator(); it.hasNext();) {
0336: element = (JRPrintElement) it.next();
0337:
0338: if (element instanceof JRPrintLine) {
0339: exportLine((JRPrintLine) element);
0340: } else if (element instanceof JRPrintRectangle) {
0341: exportRectangle((JRPrintRectangle) element);
0342: } else if (element instanceof JRPrintEllipse) {
0343: exportEllipse((JRPrintEllipse) element);
0344: } else if (element instanceof JRPrintImage) {
0345: //exportImage((JRPrintImage)element);
0346: } else if (element instanceof JRPrintText) {
0347: exportText((JRPrintText) element);
0348: } else if (element instanceof JRPrintFrame) {
0349: //exportFrame((JRPrintFrame) element);
0350: }
0351: }
0352: }
0353: }
0354:
0355: /**
0356: *
0357: */
0358: protected void exportLine(JRPrintLine line) throws IOException {
0359: tempBodyWriter.write("\n<draw:line text:anchor-type=\"page\""
0360: + " text:anchor-page-number=\""
0361: + (pageIndex + 1)
0362: + "\""
0363: + " svg:x2=\""
0364: + Utility.translatePixelsToInches(line.getX()
0365: + line.getWidth())
0366: + "in\""
0367: + " svg:y2=\""
0368: + Utility.translatePixelsToInches(line.getY()
0369: + line.getHeight()) + "in\"" + " svg:x1=\""
0370: + Utility.translatePixelsToInches(line.getX()) + "in\""
0371: + " svg:y1=\""
0372: + Utility.translatePixelsToInches(line.getY())
0373: + "in\">" + " draw:style-name=\""
0374: + styleCache.getGraphicStyle(line) + "\""
0375: + "</draw:line>");
0376: }
0377:
0378: /**
0379: *
0380: */
0381: protected void exportRectangle(JRPrintRectangle rectangle)
0382: throws IOException {
0383: tempBodyWriter.write("<draw:rect text:anchor-type=\"page\""
0384: + " text:anchor-page-number=\""
0385: + (pageIndex + 1)
0386: + "\""
0387: + " svg:x=\""
0388: + Utility.translatePixelsToInches(rectangle.getX())
0389: + "in\""
0390: + " svg:y=\""
0391: + Utility.translatePixelsToInches(rectangle.getY())
0392: + "in\""
0393: + " svg:width=\""
0394: + Utility.translatePixelsToInches(rectangle.getWidth())
0395: + "in\""
0396: + " svg:height=\""
0397: + Utility
0398: .translatePixelsToInches(rectangle.getHeight())
0399: + "in\"" + "></draw:rect>");
0400: }
0401:
0402: /**
0403: *
0404: */
0405: protected void exportEllipse(JRPrintEllipse ellipse)
0406: throws IOException {
0407: tempBodyWriter.write("<draw:ellipse text:anchor-type=\"page\""
0408: + " text:anchor-page-number=\"" + (pageIndex + 1)
0409: + "\"" + " svg:x=\""
0410: + Utility.translatePixelsToInches(ellipse.getX())
0411: + "in\"" + " svg:y=\""
0412: + Utility.translatePixelsToInches(ellipse.getY())
0413: + "in\"" + " svg:width=\""
0414: + Utility.translatePixelsToInches(ellipse.getWidth())
0415: + "in\"" + " svg:height=\""
0416: + Utility.translatePixelsToInches(ellipse.getHeight())
0417: + "in\"" + "></draw:ellipse>");
0418: }
0419:
0420: /**
0421: *
0422: */
0423: protected void exportText(JRPrintText text) throws IOException {
0424: JRStyledText styledText = getStyledText(text);
0425:
0426: int textLength = 0;
0427:
0428: if (styledText != null) {
0429: textLength = styledText.length();
0430: }
0431:
0432: // if (isWrapBreakWord)
0433: // {
0434: // styleBuffer.append("width: " + gridCell.width + "; ");
0435: // styleBuffer.append("word-wrap: break-word; ");
0436: // }
0437:
0438: // if (text.getLineSpacing() != JRTextElement.LINE_SPACING_SINGLE)
0439: // {
0440: // styleBuffer.append("line-height: " + text.getLineSpacingFactor() + "; ");
0441: // }
0442:
0443: // if (styleBuffer.length() > 0)
0444: // {
0445: // writer.write(" style=\"");
0446: // writer.write(styleBuffer.toString());
0447: // writer.write("\"");
0448: // }
0449: //
0450: // writer.write(">");
0451:
0452: // if (text.getAnchorName() != null)
0453: // {
0454: // writer.write("<a name=\"");
0455: // writer.write(text.getAnchorName());
0456: // writer.write("\"/>");
0457: // }
0458:
0459: // boolean startedHyperlink = startHyperlink(text);
0460:
0461: tempBodyWriter.write("<draw:frame text:anchor-type=\"page\""
0462: + " text:anchor-page-number=\"" + (pageIndex + 1)
0463: + "\"" + " draw:style-name=\""
0464: + styleCache.getFrameStyle(text) + "\"" + " svg:x=\""
0465: + Utility.translatePixelsToInches(text.getX()) + "in\""
0466: + " svg:y=\""
0467: + Utility.translatePixelsToInches(text.getY()) + "in\""
0468: + " svg:width=\""
0469: + Utility.translatePixelsToInches(text.getWidth())
0470: + "in\"" + " svg:height=\""
0471: + Utility.translatePixelsToInches(text.getHeight())
0472: + "in\"" + "><draw:text-box>");
0473: tempBodyWriter.write("<text:p");
0474: tempBodyWriter.write(" text:style-name=\""
0475: + styleCache.getParagraphStyle(text) + "\"");
0476: tempBodyWriter.write(">");
0477:
0478: if (textLength > 0) {
0479: exportStyledText(styledText);
0480: }
0481:
0482: // if (startedHyperlink)
0483: // {
0484: // endHyperlink();
0485: // }
0486:
0487: tempBodyWriter.write("</text:p>\n");
0488: tempBodyWriter.write("</draw:text-box></draw:frame>");
0489: }
0490:
0491: /**
0492: *
0493: *
0494: protected void exportText(TableBuilder tableBuilder, JRPrintText text, JRExporterGridCell gridCell) throws IOException
0495: {
0496: tableBuilder.buildCellStyleHeader(text);
0497: tableBuilder.buildCellBackcolorStyle(text);
0498: tableBuilder.buildCellBorderStyle(text, text);
0499: tableBuilder.buildCellAlignmentStyle(text);
0500: tableBuilder.buildCellStyleFooter();
0501: tableBuilder.buildCellHeader(gridCell.colSpan, gridCell.rowSpan);
0502:
0503: JRStyledText styledText = getStyledText(text);
0504:
0505: int textLength = 0;
0506:
0507: if (styledText != null)
0508: {
0509: textLength = styledText.length();
0510: }
0511:
0512: StringBuffer paragraphStyleIdBuffer = new StringBuffer();
0513:
0514: String verticalAlignment = VERTICAL_ALIGN_TOP;
0515: switch (text.getVerticalAlignment())
0516: {
0517: case JRAlignment.VERTICAL_ALIGN_BOTTOM :
0518: {
0519: verticalAlignment = VERTICAL_ALIGN_BOTTOM;
0520: break;
0521: }
0522: case JRAlignment.VERTICAL_ALIGN_MIDDLE :
0523: {
0524: verticalAlignment = VERTICAL_ALIGN_MIDDLE;
0525: break;
0526: }
0527: case JRAlignment.VERTICAL_ALIGN_TOP :
0528: default :
0529: {
0530: verticalAlignment = VERTICAL_ALIGN_TOP;
0531: }
0532: }
0533: paragraphStyleIdBuffer.append(verticalAlignment);
0534:
0535: String runDirection = null;
0536: if (text.getRunDirection() == JRPrintText.RUN_DIRECTION_RTL)
0537: {
0538: runDirection = "rl";
0539: }
0540: paragraphStyleIdBuffer.append(runDirection);
0541:
0542: String horizontalAlignment = HORIZONTAL_ALIGN_LEFT;
0543: switch (text.getHorizontalAlignment())
0544: {
0545: case JRAlignment.HORIZONTAL_ALIGN_RIGHT :
0546: {
0547: horizontalAlignment = HORIZONTAL_ALIGN_RIGHT;
0548: break;
0549: }
0550: case JRAlignment.HORIZONTAL_ALIGN_CENTER :
0551: {
0552: horizontalAlignment = HORIZONTAL_ALIGN_CENTER;
0553: break;
0554: }
0555: case JRAlignment.HORIZONTAL_ALIGN_JUSTIFIED :
0556: {
0557: horizontalAlignment = HORIZONTAL_ALIGN_JUSTIFY;
0558: break;
0559: }
0560: case JRAlignment.HORIZONTAL_ALIGN_LEFT :
0561: default :
0562: {
0563: horizontalAlignment = HORIZONTAL_ALIGN_LEFT;
0564: }
0565: }
0566: paragraphStyleIdBuffer.append(horizontalAlignment);
0567:
0568: // if (isWrapBreakWord)
0569: // {
0570: // styleBuffer.append("width: " + gridCell.width + "; ");
0571: // styleBuffer.append("word-wrap: break-word; ");
0572: // }
0573:
0574: // if (text.getLineSpacing() != JRTextElement.LINE_SPACING_SINGLE)
0575: // {
0576: // styleBuffer.append("line-height: " + text.getLineSpacingFactor() + "; ");
0577: // }
0578:
0579: // if (styleBuffer.length() > 0)
0580: // {
0581: // writer.write(" style=\"");
0582: // writer.write(styleBuffer.toString());
0583: // writer.write("\"");
0584: // }
0585: //
0586: // writer.write(">");
0587:
0588: // if (text.getAnchorName() != null)
0589: // {
0590: // writer.write("<a name=\"");
0591: // writer.write(text.getAnchorName());
0592: // writer.write("\"/>");
0593: // }
0594:
0595: // boolean startedHyperlink = startHyperlink(text);
0596:
0597: String paragraphStyleId = paragraphStyleIdBuffer.toString();
0598: String paragraphStyleName = (String)paragraphStyles.get(paragraphStyleId);
0599: if (paragraphStyleName == null)
0600: {
0601: paragraphStyleName = "P" + paragraphStylesCounter++;
0602: paragraphStyles.put(paragraphStyleId, paragraphStyleName);
0603:
0604: tempStyleWriter.write("<style:style style:name=\"" + paragraphStyleName + "\"");
0605: tempStyleWriter.write(" style:family=\"paragraph\">\n");
0606: tempStyleWriter.write("<style:paragraph-properties");
0607: // tempStyleWriter.write(" fo:line-height=\"" + pLineHeight + "\"");
0608: // tempStyleWriter.write(" style:line-spacing=\"" + pLineSpacing + "\"");
0609: tempStyleWriter.write(" fo:text-align=\"" + horizontalAlignment + "\"");
0610: // tempStyleWriter.write(" fo:keep-together=\"" + pKeepTogether + "\"");
0611: // tempStyleWriter.write(" fo:margin-left=\"" + pMarginLeft + "\"");
0612: // tempStyleWriter.write(" fo:margin-right=\"" + pMarginRight + "\"");
0613: // tempStyleWriter.write(" fo:margin-top=\"" + pMarginTop + "\"");
0614: // tempStyleWriter.write(" fo:margin-bottom=\"" + pMarginBottom + "\"");
0615: // tempStyleWriter.write(" fo:background-color=\"#" + pBackGroundColor + "\"");
0616: tempStyleWriter.write(" style:vertical-align=\"" + verticalAlignment + "\"");
0617: if (runDirection != null)
0618: {
0619: tempStyleWriter.write(" style:writing-mode=\"" + runDirection + "\"");
0620: }
0621: tempStyleWriter.write("> \r\n");
0622: tempStyleWriter.write("</style:paragraph-properties>\n");
0623: tempStyleWriter.write("</style:style>\n");
0624: }
0625:
0626: tempBodyWriter.write("<text:p");
0627: tempBodyWriter.write(" text:style-name=\"" + paragraphStyleName + "\"");
0628: tempBodyWriter.write(">");
0629:
0630: if (textLength > 0)
0631: {
0632: exportStyledText(styledText);
0633: }
0634:
0635: // if (startedHyperlink)
0636: // {
0637: // endHyperlink();
0638: // }
0639:
0640: tempBodyWriter.write("</text:p>\n");
0641:
0642: tableBuilder.buildCellFooter();
0643: }
0644:
0645:
0646: /**
0647: *
0648: */
0649: protected void exportStyledText(JRStyledText styledText)
0650: throws IOException {
0651: String text = styledText.getText();
0652:
0653: int runLimit = 0;
0654:
0655: AttributedCharacterIterator iterator = styledText
0656: .getAttributedString().getIterator();
0657:
0658: while (runLimit < styledText.length()
0659: && (runLimit = iterator.getRunLimit()) <= styledText
0660: .length()) {
0661: exportStyledTextRun(iterator.getAttributes(), text
0662: .substring(iterator.getIndex(), runLimit));
0663:
0664: iterator.setIndex(runLimit);
0665: }
0666: }
0667:
0668: /**
0669: *
0670: */
0671: protected void exportStyledTextRun(Map attributes, String text)
0672: throws IOException {
0673: String textRunStyleName = styleCache.getTextSpanStyle(
0674: attributes, text);
0675:
0676: tempBodyWriter.write("<text:span");
0677: tempBodyWriter.write(" text:style-name=\"" + textRunStyleName
0678: + "\"");
0679: tempBodyWriter.write(">");
0680:
0681: if (text != null) {
0682: tempBodyWriter.write(Utility
0683: .replaceNewLineWithLineBreak(JRStringUtil
0684: .xmlEncode(text)));//FIXMEODT try something nicer for replace
0685: }
0686:
0687: tempBodyWriter.write("</text:span>");
0688: }
0689:
0690: /**
0691: *
0692: *
0693: protected boolean startHyperlink(JRPrintHyperlink link) throws IOException
0694: {
0695: String href = getHyperlinkURL(link);
0696:
0697: if (href != null)
0698: {
0699: writer.write("<a href=\"");
0700: writer.write(href);
0701: writer.write("\"");
0702:
0703: String target = getHyperlinkTarget(link);
0704: if (target != null)
0705: {
0706: writer.write(" target=\"");
0707: writer.write(target);
0708: writer.write("\"");
0709: }
0710:
0711: if (link.getHyperlinkTooltip() != null)
0712: {
0713: writer.write(" title=\"");
0714: writer.write(JRStringUtil.xmlEncode(link.getHyperlinkTooltip()));
0715: writer.write("\"");
0716: }
0717:
0718: writer.write(">");
0719: }
0720:
0721: return href != null;
0722: }
0723:
0724:
0725: protected String getHyperlinkTarget(JRPrintHyperlink link)
0726: {
0727: String target = null;
0728: switch(link.getHyperlinkTarget())
0729: {
0730: case JRHyperlink.HYPERLINK_TARGET_BLANK :
0731: {
0732: target = "_blank";
0733: break;
0734: }
0735: case JRHyperlink.HYPERLINK_TARGET_SELF :
0736: default :
0737: {
0738: break;
0739: }
0740: }
0741: return target;
0742: }
0743:
0744:
0745: protected String getHyperlinkURL(JRPrintHyperlink link)
0746: {
0747: String href = null;
0748: JRHyperlinkProducer customHandler = getCustomHandler(link);
0749: if (customHandler == null)
0750: {
0751: switch(link.getHyperlinkType())
0752: {
0753: case JRHyperlink.HYPERLINK_TYPE_REFERENCE :
0754: {
0755: if (link.getHyperlinkReference() != null)
0756: {
0757: href = link.getHyperlinkReference();
0758: }
0759: break;
0760: }
0761: case JRHyperlink.HYPERLINK_TYPE_LOCAL_ANCHOR :
0762: {
0763: if (link.getHyperlinkAnchor() != null)
0764: {
0765: href = "#" + link.getHyperlinkAnchor();
0766: }
0767: break;
0768: }
0769: case JRHyperlink.HYPERLINK_TYPE_LOCAL_PAGE :
0770: {
0771: if (link.getHyperlinkPage() != null)
0772: {
0773: href = "#" + JR_PAGE_ANCHOR_PREFIX + reportIndex + "_" + link.getHyperlinkPage().toString();
0774: }
0775: break;
0776: }
0777: case JRHyperlink.HYPERLINK_TYPE_REMOTE_ANCHOR :
0778: {
0779: if (
0780: link.getHyperlinkReference() != null &&
0781: link.getHyperlinkAnchor() != null
0782: )
0783: {
0784: href = link.getHyperlinkReference() + "#" + link.getHyperlinkAnchor();
0785: }
0786: break;
0787: }
0788: case JRHyperlink.HYPERLINK_TYPE_REMOTE_PAGE :
0789: {
0790: if (
0791: link.getHyperlinkReference() != null &&
0792: link.getHyperlinkPage() != null
0793: )
0794: {
0795: href = link.getHyperlinkReference() + "#" + JR_PAGE_ANCHOR_PREFIX + "0_" + link.getHyperlinkPage().toString();
0796: }
0797: break;
0798: }
0799: case JRHyperlink.HYPERLINK_TYPE_NONE :
0800: default :
0801: {
0802: break;
0803: }
0804: }
0805: }
0806: else
0807: {
0808: href = customHandler.getHyperlink(link);
0809: }
0810:
0811: return href;
0812: }
0813:
0814:
0815: protected JRHyperlinkProducer getCustomHandler(JRPrintHyperlink link)
0816: {
0817: return hyperlinkProducerFactory == null ? null : hyperlinkProducerFactory.getHandler(link.getLinkType());
0818: }
0819:
0820:
0821: protected void endHyperlink() throws IOException
0822: {
0823: writer.write("</a>");
0824: }
0825:
0826:
0827: protected Color appendBackcolorStyle(JRPrintElement element, StringBuffer styleBuffer)
0828: {
0829: if (element.getMode() == JRElement.MODE_OPAQUE && (backcolor == null || element.getBackcolor().getRGB() != backcolor.getRGB()))
0830: {
0831: styleBuffer.append("background-color: #");
0832: String hexa = Integer.toHexString(element.getBackcolor().getRGB() & colorMask).toUpperCase();
0833: hexa = ("000000" + hexa).substring(hexa.length());
0834: styleBuffer.append(hexa);
0835: styleBuffer.append("; ");
0836:
0837: return element.getBackcolor();
0838: }
0839:
0840: return null;
0841: }
0842:
0843:
0844: /**
0845: *
0846: *
0847: protected void exportImage(TableBuilder tableBuilder, JRPrintImage image, JRExporterGridCell gridCell) throws IOException
0848: {
0849: tableBuilder.buildCellStyleHeader(image);
0850: tableBuilder.buildCellBackcolorStyle(image);
0851: tableBuilder.buildCellBorderStyle(image, getBox(image));
0852: tableBuilder.buildCellStyleFooter();
0853: tableBuilder.buildCellHeader(gridCell.colSpan, gridCell.rowSpan);
0854: tableBuilder.buildCellFooter();
0855: }
0856:
0857:
0858: /**
0859: *
0860: *
0861: protected void exportImage(JRPrintImage image, JRExporterGridCell gridCell) throws JRException, IOException
0862: {
0863: writeCellTDStart(gridCell);
0864:
0865: String horizontalAlignment = CSS_TEXT_ALIGN_LEFT;
0866:
0867: switch (image.getHorizontalAlignment())
0868: {
0869: case JRAlignment.HORIZONTAL_ALIGN_RIGHT :
0870: {
0871: horizontalAlignment = CSS_TEXT_ALIGN_RIGHT;
0872: break;
0873: }
0874: case JRAlignment.HORIZONTAL_ALIGN_CENTER :
0875: {
0876: horizontalAlignment = CSS_TEXT_ALIGN_CENTER;
0877: break;
0878: }
0879: case JRAlignment.HORIZONTAL_ALIGN_LEFT :
0880: default :
0881: {
0882: horizontalAlignment = CSS_TEXT_ALIGN_LEFT;
0883: }
0884: }
0885:
0886: if (!horizontalAlignment.equals(CSS_TEXT_ALIGN_LEFT))
0887: {
0888: writer.write(" align=\"");
0889: writer.write(horizontalAlignment);
0890: writer.write("\"");
0891: }
0892:
0893: String verticalAlignment = HTML_VERTICAL_ALIGN_TOP;
0894:
0895: switch (image.getVerticalAlignment())
0896: {
0897: case JRAlignment.VERTICAL_ALIGN_BOTTOM :
0898: {
0899: verticalAlignment = HTML_VERTICAL_ALIGN_BOTTOM;
0900: break;
0901: }
0902: case JRAlignment.VERTICAL_ALIGN_MIDDLE :
0903: {
0904: verticalAlignment = HTML_VERTICAL_ALIGN_MIDDLE;
0905: break;
0906: }
0907: case JRAlignment.VERTICAL_ALIGN_TOP :
0908: default :
0909: {
0910: verticalAlignment = HTML_VERTICAL_ALIGN_TOP;
0911: }
0912: }
0913:
0914: if (!verticalAlignment.equals(HTML_VERTICAL_ALIGN_TOP))
0915: {
0916: writer.write(" valign=\"");
0917: writer.write(verticalAlignment);
0918: writer.write("\"");
0919: }
0920:
0921: StringBuffer styleBuffer = new StringBuffer();
0922: appendBackcolorStyle(image, styleBuffer);
0923: appendBorderStyle(image, image, styleBuffer);
0924:
0925: if (styleBuffer.length() > 0)
0926: {
0927: writer.write(" style=\"");
0928: writer.write(styleBuffer.toString());
0929: writer.write("\"");
0930: }
0931:
0932: writer.write(">");
0933:
0934: if (image.getAnchorName() != null)
0935: {
0936: writer.write("<a name=\"");
0937: writer.write(image.getAnchorName());
0938: writer.write("\"/>");
0939: }
0940:
0941: JRRenderable renderer = image.getRenderer();
0942: JRRenderable originalRenderer = renderer;
0943: boolean imageMapRenderer = renderer != null && renderer instanceof JRImageMapRenderer;
0944:
0945: boolean startedHyperlink = false;
0946:
0947: if(renderer != null)
0948: {
0949: startedHyperlink = !imageMapRenderer && startHyperlink(image);
0950: writer.write("<img");
0951: String imagePath = null;
0952: String imageMapName = null;
0953: List imageMapAreas = null;
0954:
0955: byte scaleImage = image.getScaleImage();
0956: if (renderer.getType() == JRRenderable.TYPE_IMAGE && rendererToImagePathMap.containsKey(renderer.getId()))
0957: {
0958: imagePath = (String)rendererToImagePathMap.get(renderer.getId());
0959: }
0960: else
0961: {
0962: if (image.isLazy())
0963: {
0964: imagePath = ((JRImageRenderer)renderer).getImageLocation();
0965: }
0966: else
0967: {
0968: JRPrintElementIndex imageIndex = getElementIndex(gridCell);
0969: imagesToProcess.add(imageIndex);
0970:
0971: String imageName = getImageName(imageIndex);
0972: imagePath = "imagesURI" + imageName;
0973: }
0974:
0975: rendererToImagePathMap.put(renderer.getId(), imagePath);
0976: }
0977:
0978: if (imageMapRenderer)
0979: {
0980: Rectangle renderingArea = new Rectangle(image.getWidth(), image.getHeight());
0981:
0982: if (renderer.getType() == JRRenderable.TYPE_IMAGE)
0983: {
0984: imageMapName = (String) imageMaps.get(new Pair(renderer.getId(), renderingArea));
0985: }
0986:
0987: if (imageMapName == null)
0988: {
0989: imageMapName = "map_" + getElementIndex(gridCell).toString();
0990: imageMapAreas = ((JRImageMapRenderer) originalRenderer).getImageAreaHyperlinks(renderingArea);
0991:
0992: if (renderer.getType() == JRRenderable.TYPE_IMAGE)
0993: {
0994: imageMaps.put(new Pair(renderer.getId(), renderingArea), imageMapName);
0995: }
0996: }
0997: }
0998:
0999: writer.write(" src=\"");
1000: if (imagePath != null)
1001: writer.write(imagePath);
1002: writer.write("\"");
1003:
1004: int borderWidth = 0;
1005: switch (image.getPen())
1006: {
1007: case JRGraphicElement.PEN_DOTTED :
1008: {
1009: borderWidth = 1;
1010: break;
1011: }
1012: case JRGraphicElement.PEN_4_POINT :
1013: {
1014: borderWidth = 4;
1015: break;
1016: }
1017: case JRGraphicElement.PEN_2_POINT :
1018: {
1019: borderWidth = 2;
1020: break;
1021: }
1022: case JRGraphicElement.PEN_NONE :
1023: {
1024: borderWidth = 0;
1025: break;
1026: }
1027: case JRGraphicElement.PEN_THIN :
1028: {
1029: borderWidth = 1;
1030: break;
1031: }
1032: case JRGraphicElement.PEN_1_POINT :
1033: default :
1034: {
1035: borderWidth = 1;
1036: break;
1037: }
1038: }
1039:
1040: writer.write(" border=\"");
1041: writer.write(String.valueOf(borderWidth));
1042: writer.write("\"");
1043:
1044: int imageWidth = image.getWidth() - image.getLeftPadding() - image.getRightPadding();
1045: if (imageWidth < 0)
1046: {
1047: imageWidth = 0;
1048: }
1049:
1050: int imageHeight = image.getHeight() - image.getTopPadding() - image.getBottomPadding();
1051: if (imageHeight < 0)
1052: {
1053: imageHeight = 0;
1054: }
1055:
1056: switch (scaleImage)
1057: {
1058: case JRImage.SCALE_IMAGE_FILL_FRAME :
1059: {
1060: writer.write(" style=\"width: ");
1061: writer.write(String.valueOf(imageWidth));
1062: writer.write("; height: ");
1063: writer.write(String.valueOf(imageHeight));
1064: writer.write("\"");
1065:
1066: break;
1067: }
1068: case JRImage.SCALE_IMAGE_CLIP : //FIXMEIMAGE image clip could be achieved by cutting the image and preserving the image type
1069: case JRImage.SCALE_IMAGE_RETAIN_SHAPE :
1070: default :
1071: {
1072: double normalWidth = imageWidth;
1073: double normalHeight = imageHeight;
1074:
1075: if (!image.isLazy())
1076: {
1077: Dimension2D dimension = renderer.getDimension();
1078: if (dimension != null)
1079: {
1080: normalWidth = dimension.getWidth();
1081: normalHeight = dimension.getHeight();
1082: }
1083: }
1084:
1085: if (imageHeight > 0)
1086: {
1087: double ratio = normalWidth / normalHeight;
1088:
1089: if( ratio > (double)imageWidth / (double)imageHeight )
1090: {
1091: writer.write(" style=\"width: ");
1092: writer.write(String.valueOf(imageWidth));
1093: writer.write("\"");
1094: }
1095: else
1096: {
1097: writer.write(" style=\"height: ");
1098: writer.write(String.valueOf(imageHeight));
1099: writer.write("\"");
1100: }
1101: }
1102: }
1103: }
1104:
1105: if (imageMapName != null)
1106: {
1107: writer.write(" usemap=\"#" + imageMapName + "\"");
1108: }
1109:
1110: writer.write(" alt=\"\"/>");
1111:
1112: if (startedHyperlink)
1113: {
1114: endHyperlink();
1115: }
1116:
1117: if (imageMapAreas != null)
1118: {
1119: writer.write("\n");
1120: writeImageMap(imageMapName, image, imageMapAreas);
1121: }
1122: }
1123: writer.write("</td>\n");
1124: }
1125:
1126:
1127: protected JRPrintElementIndex getElementIndex(JRExporterGridCell gridCell)
1128: {
1129: JRPrintElementIndex imageIndex =
1130: new JRPrintElementIndex(
1131: reportIndex,
1132: pageIndex,
1133: gridCell.elementIndex
1134: );
1135: return imageIndex;
1136: }
1137:
1138:
1139: protected void writeImageMap(String imageMapName, JRPrintHyperlink mainHyperlink, List imageMapAreas) throws IOException
1140: {
1141: writer.write("<map name=\"" + imageMapName + "\">\n");
1142:
1143: for (Iterator it = imageMapAreas.iterator(); it.hasNext();)
1144: {
1145: JRPrintImageAreaHyperlink areaHyperlink = (JRPrintImageAreaHyperlink) it.next();
1146: JRPrintImageArea area = areaHyperlink.getArea();
1147:
1148: writer.write(" <area shape=\"" + JRPrintImageArea.getHtmlShape(area.getShape()) + "\"");
1149: writeImageAreaCoordinates(area);
1150: writeImageAreaHyperlink(areaHyperlink.getHyperlink());
1151: writer.write("/>\n");
1152: }
1153:
1154: if (mainHyperlink.getHyperlinkType() != JRHyperlink.HYPERLINK_TYPE_NONE)
1155: {
1156: writer.write(" <area shape=\"default\"");
1157: writeImageAreaHyperlink(mainHyperlink);
1158: writer.write("/>\n");
1159: }
1160:
1161: writer.write("</map>\n");
1162: }
1163:
1164:
1165: protected void writeImageAreaCoordinates(JRPrintImageArea area) throws IOException
1166: {
1167: int[] coords = area.getCoordinates();
1168: if (coords != null && coords.length > 0)
1169: {
1170: StringBuffer coordsEnum = new StringBuffer(coords.length * 4);
1171: coordsEnum.append(coords[0]);
1172: for (int i = 1; i < coords.length; i++)
1173: {
1174: coordsEnum.append(',');
1175: coordsEnum.append(coords[i]);
1176: }
1177:
1178: writer.write(" coords=\"" + coordsEnum + "\"");
1179: }
1180: }
1181:
1182:
1183: protected void writeImageAreaHyperlink(JRPrintHyperlink hyperlink) throws IOException
1184: {
1185: String href = getHyperlinkURL(hyperlink);
1186: if (href == null)
1187: {
1188: writer.write(" nohref=\"nohref\"");
1189: }
1190: else
1191: {
1192: writer.write(" href=\"" + href + "\"");
1193:
1194: String target = getHyperlinkTarget(hyperlink);
1195: if (target != null)
1196: {
1197: writer.write(" target=\"");
1198: writer.write(target);
1199: writer.write("\"");
1200: }
1201: }
1202:
1203: if (hyperlink.getHyperlinkTooltip() != null)
1204: {
1205: writer.write(" title=\"");
1206: writer.write(JRStringUtil.xmlEncode(hyperlink.getHyperlinkTooltip()));
1207: writer.write("\"");
1208: }
1209: }
1210:
1211:
1212: /**
1213: *
1214: *
1215: public static String getImageName(JRPrintElementIndex printElementIndex)
1216: {
1217: return IMAGE_NAME_PREFIX + printElementIndex.toString();
1218: }
1219:
1220:
1221: /**
1222: *
1223: *
1224: public static JRPrintElementIndex getPrintElementIndex(String imageName)
1225: {
1226: if (!imageName.startsWith(IMAGE_NAME_PREFIX))
1227: {
1228: throw new JRRuntimeException("Invalid image name: " + imageName);
1229: }
1230:
1231: return JRPrintElementIndex.parsePrintElementIndex(imageName.substring(IMAGE_NAME_PREFIX_LEGTH));
1232: }
1233:
1234:
1235: /**
1236: *
1237: *
1238: protected void exportFrame(TableBuilder tableBuilder, JRPrintFrame frame, JRExporterGridCell gridCell) throws IOException, JRException
1239: {
1240: tableBuilder.buildCellStyleHeader(frame);
1241: tableBuilder.buildCellStyleFooter();
1242: tableBuilder.buildCellHeader(gridCell.colSpan, gridCell.rowSpan);
1243:
1244: // StringBuffer styleBuffer = new StringBuffer();
1245: // Color frameBackcolor = appendBackcolorStyle(frame, styleBuffer);
1246: // appendBorderStyle(frame, frame, styleBuffer);
1247: //
1248: // if (styleBuffer.length() > 0)
1249: // {
1250: // writer.write(" style=\"");
1251: // writer.write(styleBuffer.toString());
1252: // writer.write("\"");
1253: // }
1254: //
1255: // writer.write(">\n");
1256: //
1257: // if (frameBackcolor != null)
1258: // {
1259: // setBackcolor(frameBackcolor);
1260: // }
1261: try
1262: {
1263: exportElements(frame.getElements());
1264: }
1265: finally
1266: {
1267: // if (frameBackcolor != null)
1268: // {
1269: // restoreBackcolor();
1270: // }
1271: }
1272:
1273: tableBuilder.buildCellFooter();
1274: }
1275:
1276: /**
1277: *
1278: *
1279: protected void setBackcolor(Color color)
1280: {
1281: backcolorStack.addLast(backcolor);
1282:
1283: backcolor = color;
1284: }
1285:
1286:
1287: protected void restoreBackcolor()
1288: {
1289: backcolor = (Color) backcolorStack.removeLast();
1290: }
1291: */
1292:
1293: }
|