1 13 package org.pentaho.plugin.jfreereport.reportcharts; 14 15 import java.awt.BasicStroke ; 16 import java.awt.Color ; 17 import java.awt.Font ; 18 import java.awt.Image ; 19 import java.awt.Stroke ; 20 import java.awt.Toolkit ; 21 import java.io.File ; 22 import java.io.IOException ; 23 import java.text.MessageFormat ; 24 import java.util.HashMap ; 25 import java.util.Map ; 26 27 import org.jfree.chart.ChartRenderingInfo; 28 import org.jfree.chart.ChartUtilities; 29 import org.jfree.chart.JFreeChart; 30 import org.jfree.chart.block.BlockBorder; 31 import org.jfree.chart.plot.Plot; 32 import org.jfree.chart.title.LegendTitle; 33 import org.jfree.fonts.StringUtilities; 34 import org.jfree.report.function.AbstractExpression; 35 import org.jfree.report.function.Expression; 36 import org.jfree.ui.RectangleEdge; 37 import org.jfree.util.Log; 38 import org.pentaho.core.session.IPentahoSession; 39 import org.pentaho.core.session.StandaloneSession; 40 import org.pentaho.core.system.IApplicationContext; 41 import org.pentaho.core.system.PentahoSystem; 42 import org.pentaho.messages.Messages; 43 import org.pentaho.plugin.jfreechart.JFreeChartEngine; 44 import org.pentaho.util.ColorHelper; 45 46 public abstract class AbstractChartExpression extends AbstractExpression { 47 50 protected static final Stroke EmptyStroke = new BasicStroke (0.0f); 51 52 private static Map LEGEND_LOCATIONS; 53 54 private String dataSource; 55 56 private String title; 57 58 private boolean antiAlias = true; 59 60 private String legendLocation; 61 62 private String titleFont = "SansSerif-BOLD-14"; 64 private String labelFont = "SansSerif--8"; 66 private String legendFont = "SansSerif--8"; 68 private int chartWidth; 69 70 private int chartHeight; 71 72 private boolean showBorder; 73 74 private String borderColor; 75 76 private String backgroundColor; 77 78 private boolean drawLegendBorder = true; 79 80 private boolean showLegend; 81 82 private boolean threeD; 83 84 private boolean chartSectionOutline; 85 86 private boolean useDrawable = true; 87 88 private String backgroundImage; 89 90 private String chartDirectory; 91 92 private String chartFile; 93 94 private String chartUrlMask; 95 96 private boolean returnFileNameOnly; 97 98 private boolean returnImageReference; 99 100 private HashMap valueCache = new HashMap (); 101 102 public static final String CACHE_ENABLED_CONFIG = "org.pentaho.plugin.jfreereport.CacheChartExpressionResults"; 104 public static final String CACHE_ENABLED_DEFAULT = "true"; 106 public static final int MAX_CACHE_ITEMS = 10; 107 108 private HashMap chartCache = new HashMap (); 109 110 private IPentahoSession session; 111 112 protected AbstractChartExpression() { 113 session = new StandaloneSession("ChartExpression"); } 115 116 protected AbstractChartExpression(IPentahoSession session) { 117 this.session = session; 118 } 119 120 private RectangleEdge translateEdge(String edge) { 121 if (LEGEND_LOCATIONS == null) { 122 LEGEND_LOCATIONS = new HashMap (); 123 LEGEND_LOCATIONS.put("left", RectangleEdge.LEFT); LEGEND_LOCATIONS.put("west", RectangleEdge.LEFT); LEGEND_LOCATIONS.put("right", RectangleEdge.RIGHT); LEGEND_LOCATIONS.put("east", RectangleEdge.RIGHT); LEGEND_LOCATIONS.put("top", RectangleEdge.TOP); LEGEND_LOCATIONS.put("north", RectangleEdge.TOP); LEGEND_LOCATIONS.put("bottom", RectangleEdge.BOTTOM); LEGEND_LOCATIONS.put("south", RectangleEdge.BOTTOM); } 132 final RectangleEdge translatedEdge = (RectangleEdge) LEGEND_LOCATIONS.get(edge); 133 if (translatedEdge != null) { 134 return translatedEdge; 135 } 136 return RectangleEdge.LEFT; 137 } 138 139 public String getTitleFont() { 140 return titleFont; 141 } 142 143 public void setTitleFont(final String value) { 144 this.titleFont = value; 145 } 146 147 public String getLegendFont() { 148 return legendFont; 149 } 150 151 public void setLegendFont(String value) { 152 legendFont = value; 153 } 154 155 public String getLabelFont() { 156 return labelFont; 157 } 158 159 public void setLabelFont(final String value) { 160 this.labelFont = value; 161 } 162 163 public void setChartDirectory(String value) { 164 chartDirectory = value; 165 } 166 167 public void setChartFile(String value) { 168 chartFile = value; 169 } 170 171 public void setChartUrlMask(String value) { 172 chartUrlMask = value; 173 } 174 175 public String getChartDirectory() { 176 return chartDirectory; 177 } 178 179 public String getChartFile() { 180 return chartFile; 181 } 182 183 public String getChartUrlMask() { 184 return chartUrlMask; 185 } 186 187 public String getDataSource() { 188 return dataSource; 189 } 190 191 public void setDataSource(final String dataSource) { 192 this.dataSource = dataSource; 193 } 194 195 public String getTitle() { 196 return getPossibleExpressionStringValue(title); 197 } 198 199 public boolean isReturnFileNameOnly() { 200 return returnFileNameOnly; 201 } 202 203 public void setReturnFileNameOnly(boolean value) { 204 returnFileNameOnly = value; 205 } 206 207 public String getPossibleExpressionStringValue(String lookupValue) { 208 if (lookupValue == null) { 209 return null; 210 } 211 212 Object maybeExpression = null; 213 try { 214 maybeExpression = getDataRow().get(lookupValue); 215 } catch (Exception ignored) { 216 } 218 if (maybeExpression != null) { 219 return maybeExpression.toString(); 220 } else { 221 return lookupValue; 222 } 223 } 224 225 public void setTitle(final String title) { 226 this.title = title; 227 } 228 229 public void setChartWidth(int value) { 230 chartWidth = value; 231 } 232 233 public int getChartWidth() { 234 return chartWidth; 235 } 236 237 public void setChartHeight(int value) { 238 chartHeight = value; 239 } 240 241 public int getChartHeight() { 242 return chartHeight; 243 } 244 245 public boolean isAntiAlias() { 246 return antiAlias; 247 } 248 249 public void setAntiAlias(final boolean value) { 250 antiAlias = value; 251 } 252 253 public String getBorderColor() { 254 return borderColor; 255 } 256 257 public void setBorderColor(String value) { 258 borderColor = value; 259 } 260 261 public String getBackgroundColor() { 262 return backgroundColor; 263 } 264 265 public void setBackgroundColor(String value) { 266 backgroundColor = value; 267 } 268 269 public boolean isShowBorder() { 270 return showBorder; 271 } 272 273 public void setShowBorder(boolean value) { 274 showBorder = value; 275 } 276 277 public String getLegendLocation() { 278 return legendLocation; 279 } 280 281 public void setLegendLocation(String value) { 282 legendLocation = value; 283 } 284 285 public boolean isDrawLegendBorder() { 286 return drawLegendBorder; 287 } 288 289 public void setDrawLegendBorder(boolean value) { 290 drawLegendBorder = value; 291 } 292 293 public boolean isShowLegend() { 294 return showLegend; 295 } 296 297 public void setShowLegend(final boolean value) { 298 showLegend = value; 299 } 300 301 public boolean isThreeD() { 302 return threeD; 303 } 304 305 public void setThreeD(final boolean value) { 306 threeD = value; 307 } 308 309 public boolean isChartSectionOutline() { 310 return chartSectionOutline; 311 } 312 313 public void setChartSectionOutline(final boolean value) { 314 chartSectionOutline = value; 315 } 316 317 public boolean isUseDrawable() { 318 return useDrawable; 319 } 320 321 public void setUseDrawable(boolean value) { 322 useDrawable = value; 323 } 324 325 public void setBackgroundImage(String value) { 326 this.backgroundImage = value; 327 } 328 329 public String getBackgroundImage() { 330 return this.backgroundImage; 331 } 332 333 public JFreeChart getChartFromCache(Object key) { 334 final Object o = chartCache.get(key); 335 JFreeChart chart = null; 336 if (o != null) { 337 chart = (JFreeChart)o; 338 } 339 return chart; 340 } 341 342 public void putChartInCache(JFreeChart chart, Object key) { 343 chartCache.put(key, chart); 344 } 345 346 351 protected Object getValue(JFreeChart chart) { 352 if (useDrawable) { 353 return chart; 354 } 355 356 final Integer row = new Integer (getRuntime().getCurrentRow()); 357 final Object o = valueCache.get(row); 358 if (o != null) { 359 return o; 360 } 361 362 try { 363 ChartRenderingInfo info = new ChartRenderingInfo(); 364 365 final boolean chartPng = isPngExport(); 366 final File file = createChartFile(); 367 368 final int chartWidth = getChartWidth(); 369 final int chartHeight = getChartHeight(); 370 if (chartPng) { 371 ChartUtilities.saveChartAsPNG(file, chart, chartWidth, chartHeight, info); 372 } else { 373 ChartUtilities.saveChartAsJPEG(file, chart, chartWidth, chartHeight, info); 374 } 375 376 Object retval; 377 if (returnFileNameOnly) { 378 retval = file.getAbsoluteFile(); 379 } else { 380 String locationString = createChartLocationString(file); 381 if (locationString != null) { 382 if (returnImageReference) { 383 384 final Image image = Toolkit.getDefaultToolkit().createImage(file.toURL()); 385 retval = new ChartImageContainer(locationString, image, chartWidth, chartHeight, row.intValue(), getName()); 386 } else { 387 retval = locationString; 388 } 389 } else { 390 retval = file.toURL(); 391 } 392 } 393 394 if (getReportConfiguration().getConfigProperty(CACHE_ENABLED_CONFIG, CACHE_ENABLED_DEFAULT).equals("true")) { valueCache.put(row, retval); 396 } 397 return retval; 398 } catch (IOException ex) { 399 Log.error(Messages.getErrorString("ABSTRACTCHARTEXPRESSION.ERROR_0001_ERROR_GENERATING_CHART"), ex); } 401 return null; 402 } 403 404 private String createChartLocationString(File file) { 405 String fName = file.getName(); 406 if (chartUrlMask != null) { 407 return MessageFormat.format(chartUrlMask, new Object [] { fName }); 408 } 409 410 IApplicationContext ctx = PentahoSystem.getApplicationContext(); 411 if (ctx != null) { 412 return ctx.getBaseUrl() + "getImage?image=" + fName; } 414 return null; 415 } 416 417 private File createChartFile() throws IOException { 418 if (chartFile != null) { 419 if (isPngExport() && StringUtilities.endsWithIgnoreCase(chartFile, ".PNG") == false) { 421 chartFile = chartFile + ".png"; } 423 424 File file = new File (chartFile); 425 if (file.exists()) { 426 if (!file.isFile()) { 427 Log.error(Messages.getErrorString("ABSTRACTCHARTEXPRESSION.ERROR_0003_FILE_IS_NOT_FILE")); } else if (!file.canWrite()) { 429 Log.error(Messages.getErrorString("ABSTRACTCHARTEXPRESSION.ERROR_0004_FILE_IS_NOT_WRITABLE")); } else { 431 return file; 432 } 433 } else { 434 try { 435 if (file.createNewFile()) { 436 return file; 437 } 438 439 Log.error(Messages.getErrorString("ABSTRACTCHARTEXPRESSION.ERROR_0005_FILE_COULD_NOT_BE_CREATED")); } catch (IOException ex) { 441 Log.error(Messages.getErrorString("ABSTRACTCHARTEXPRESSION.ERROR_0005_FILE_COULD_NOT_BE_CREATED"), ex); } 443 } 444 } 445 446 File directory = getStorageDir(); 447 File file = File.createTempFile("tmp_chart", ".png", directory); file.deleteOnExit(); 449 return file; 450 } 451 452 private boolean isPngExport() { 453 boolean chartPng = true; 454 if (chartFile != null && StringUtilities.endsWithIgnoreCase(chartFile, ".jpg")) { chartPng = false; 456 } 457 return chartPng; 458 } 459 460 private File getStorageDir() { 461 if (chartDirectory != null) { 463 File directory = new File (chartDirectory); 464 if (directory.exists() && directory.isDirectory()) { 465 return directory; 466 } 467 468 Log.error(Messages.getErrorString("ABSTRACTCHARTEXPRESSION.ERROR_0002_DIRECTORY_NOT_FOUND")); } 470 471 IApplicationContext ctx = PentahoSystem.getApplicationContext(); 473 if (ctx != null) { 474 return new File (ctx.getFileOutputPath("system/tmp/")); } else { 476 Log.error(Messages.getErrorString("ABSTRACTCHARTEXPRESSION.ERROR_0006_PENTAHOSYSTEM_UNINITIALIZED")); String tempDir = System.getProperty("java.io.tmpdir"); return new File (tempDir); 479 } 480 } 481 482 protected void setChartProperties(JFreeChart chart) { 483 Font tFont = Font.decode(getTitleFont()); 485 chart.getTitle().setFont(tFont); 486 if (!isAntiAlias()) { 487 chart.setAntiAlias(false); 488 } 489 chart.setBorderVisible(isShowBorder()); 490 Color backCol = getColorFromString(backgroundColor); 491 if (backCol != null) { 492 chart.setBackgroundPaint(backCol); 493 } 494 495 Color borderCol = getColorFromString(borderColor); 496 if (borderCol != null) { 497 chart.setBorderPaint(borderCol); 498 } 499 500 if (legendLocation != null) { 501 LegendTitle chLegend = chart.getLegend(); 502 if (chLegend != null) { 503 RectangleEdge loc = translateEdge(legendLocation.toLowerCase()); 504 if (loc != null) { 505 chLegend.setPosition(loc); 506 } 507 if (getLegendFont() != null) { 508 chLegend.setItemFont(Font.decode(getLegendFont())); 509 } 510 if (!isDrawLegendBorder()) { 511 chLegend.setBorder(BlockBorder.NONE); 512 } 513 } 514 } 515 Plot plot = chart.getPlot(); 516 if (!isChartSectionOutline()) { 517 plot.setOutlineStroke(EmptyStroke); 518 } 519 if (backgroundImage != null) { 520 plot.setBackgroundImage(JFreeChartEngine.getImage(backgroundImage, getSession())); 521 } 522 523 } 524 525 protected Color getColorFromString(String colStr) { 526 if (colStr == null) { 527 return null; 528 } 529 530 try { 531 return Color.decode(colStr); 532 } catch (NumberFormatException ex) { 533 } 535 return ColorHelper.lookupColor(colStr); 536 537 } 538 539 public Expression getInstance() { 540 final AbstractChartExpression instance = (AbstractChartExpression) super.getInstance(); 541 instance.valueCache = new HashMap (); 542 return instance; 543 } 544 545 public boolean isReturnImageReference() { 546 return returnImageReference; 547 } 548 549 public void setReturnImageReference(final boolean returnImageReference) { 550 this.returnImageReference = returnImageReference; 551 } 552 553 public IPentahoSession getSession() { 554 return session; 555 } 556 557 public void setSession(IPentahoSession session) { 558 this.session = session; 559 } 560 } 561 | Popular Tags |