001: /*
002: * Copyright 2006-2007 Pentaho Corporation. All rights reserved.
003: * This software was developed by Pentaho Corporation and is provided under the terms
004: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
005: * this file except in compliance with the license. If you need a copy of the license,
006: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt.
007: *
008: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
009: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
010: * the license for the specific language governing your rights and limitations.
011: *
012: * Additional Contributor(s): Martin Schmid gridvision engineering GmbH
013: */
014: package org.pentaho.reportdesigner.crm.report.templateplugin;
015:
016: import org.jetbrains.annotations.NonNls;
017: import org.jetbrains.annotations.NotNull;
018: import org.jetbrains.annotations.Nullable;
019: import org.jfree.report.function.Expression;
020: import org.pentaho.reportdesigner.crm.report.IconLoader;
021: import org.pentaho.reportdesigner.crm.report.connection.ColumnInfo;
022: import org.pentaho.reportdesigner.crm.report.lineal.GuideLine;
023: import org.pentaho.reportdesigner.crm.report.model.BandToplevelReportElement;
024: import org.pentaho.reportdesigner.crm.report.model.BandToplevelType;
025: import org.pentaho.reportdesigner.crm.report.model.LabelReportElement;
026: import org.pentaho.reportdesigner.crm.report.model.MessageFieldReportElement;
027: import org.pentaho.reportdesigner.crm.report.model.PageDefinition;
028: import org.pentaho.reportdesigner.crm.report.model.PageFormatPreset;
029: import org.pentaho.reportdesigner.crm.report.model.PageOrientation;
030: import org.pentaho.reportdesigner.crm.report.model.Report;
031: import org.pentaho.reportdesigner.crm.report.model.ReportElement;
032: import org.pentaho.reportdesigner.crm.report.model.ReportFunctionElement;
033: import org.pentaho.reportdesigner.crm.report.model.ReportFunctionsElement;
034: import org.pentaho.reportdesigner.crm.report.model.ReportGroup;
035: import org.pentaho.reportdesigner.crm.report.model.ReportGroups;
036: import org.pentaho.reportdesigner.crm.report.model.TextFieldReportElement;
037: import org.pentaho.reportdesigner.crm.report.model.functions.ExpressionRegistry;
038: import org.pentaho.reportdesigner.crm.report.reportelementinfo.ReportElementInfoFactory;
039: import org.pentaho.reportdesigner.crm.report.wizard.WizardData;
040: import org.pentaho.reportdesigner.crm.report.wizard.reportgeneratewizard.GroupInfo;
041: import org.pentaho.reportdesigner.lib.client.i18n.TranslationManager;
042: import org.pentaho.reportdesigner.lib.client.util.DoubleDimension;
043: import org.pentaho.reportdesigner.lib.client.util.FontUtils;
044:
045: import javax.swing.*;
046: import java.awt.*;
047: import java.awt.geom.Point2D;
048: import java.lang.reflect.InvocationTargetException;
049: import java.util.ArrayList;
050: import java.util.HashMap;
051: import java.util.logging.Level;
052: import java.util.logging.Logger;
053:
054: /**
055: * User: Martin
056: * Date: 27.02.2006
057: * Time: 18:22:59
058: */
059: public class StructuredLayoutPlugin extends AbstractLayoutPlugin {
060: @NonNls
061: @NotNull
062: private static final Logger LOG = Logger
063: .getLogger(StructuredLayoutPlugin.class.getName());
064:
065: public StructuredLayoutPlugin() {
066: }
067:
068: @NotNull
069: public String getLocalizedName() {
070: return TranslationManager.getInstance().getTranslation("R",
071: "StructuredLayoutPlugin.Name");
072: }
073:
074: @NotNull
075: public ImageIcon getSampleImage() {
076: return IconLoader.getInstance().getTemplateStructuredIcon();
077: }
078:
079: public void addVisualReportElements(@NotNull
080: Report report, @NotNull
081: HashMap<String, WizardData> wizardDatas, @NotNull
082: LayoutStyle layoutStyle) throws LayoutException {
083: if (layoutStyle == null) {
084: throw new IllegalArgumentException(
085: "layoutStyle must not be null");
086: }
087:
088: @Nullable
089: WizardData visibleColumnInfoData = wizardDatas
090: .get(WizardData.VISIBLE_COLUMN_INFOS);
091: ArrayList<ColumnInfo> visibleColumnInfos = new ArrayList<ColumnInfo>();
092: if (visibleColumnInfoData != null) {
093: //noinspection unchecked
094: visibleColumnInfos = new ArrayList<ColumnInfo>(
095: (ArrayList<ColumnInfo>) visibleColumnInfoData
096: .getValue());
097: }
098:
099: @Nullable
100: WizardData columnGroupsWizardData = wizardDatas
101: .get(WizardData.COLUMN_GROUPS);
102: ArrayList<GroupInfo> columnGroups = new ArrayList<GroupInfo>();
103: if (columnGroupsWizardData != null) {
104: //noinspection unchecked
105: columnGroups = (ArrayList<GroupInfo>) columnGroupsWizardData
106: .getValue();
107: }
108:
109: @Nullable
110: WizardData pageDefinitionWizardData = wizardDatas
111: .get(WizardData.PAGE_DEFINITION);
112: PageDefinition pageDefinition;
113: if (pageDefinitionWizardData == null) {
114: pageDefinition = new PageDefinition(PageFormatPreset.A4,
115: PageOrientation.PORTRAIT, 20, 20, 20, 20);
116: } else {
117: pageDefinition = (PageDefinition) pageDefinitionWizardData
118: .getValue();
119: }
120:
121: double pageWidth = pageDefinition.getInnerPageSize().getWidth();
122:
123: BandToplevelReportElement reportHeaderBand = ReportElementInfoFactory
124: .getInstance().getBandToplevelReportElementInfo(
125: BandToplevelType.REPORT_HEADER)
126: .createReportElement();
127: LabelReportElement titleLabel = ReportElementInfoFactory
128: .getInstance().getLabelReportElementInfo()
129: .createReportElement();
130: titleLabel.setText(TranslationManager.getInstance()
131: .getTranslation("R",
132: "StructuredLayoutPlugin.ReportTitle"));
133: titleLabel.setFont(FontUtils.getFont(layoutStyle
134: .getBaseFontName(), Font.BOLD, 26));
135: titleLabel.setMinimumSize(new DoubleDimension(pageWidth, 40));
136: reportHeaderBand.addChild(titleLabel);
137:
138: ReportGroups reportGroups = ReportElementInfoFactory
139: .getInstance().getReportGroupsElementInfo()
140: .createReportElement();
141: boolean addedToToplevelReportGroups = false;
142:
143: ReportGroup parentGroup = null;
144:
145: double tableHeaderPosition = 40 + 10;
146: BandToplevelReportElement tableHeaderBand = reportHeaderBand;
147:
148: for (int i = 0; i < columnGroups.size(); i++) {
149: GroupInfo columnInfo = columnGroups.get(i);
150: ReportGroup reportGroupElement = ReportElementInfoFactory
151: .getInstance().getReportGroupElementInfo()
152: .createReportElement();
153: ArrayList<String> groupFields = new ArrayList<String>();
154: StringBuilder sb = new StringBuilder(100);
155: for (ColumnInfo info : columnInfo.getColumnInfos()) {
156: groupFields.add(info.getColumnName());
157: sb.append(info.getColumnName());
158: sb.append("_");
159: }
160: reportGroupElement.setGroupFields(groupFields
161: .toArray(new String[groupFields.size()]));
162: reportGroupElement.setName(sb.toString() + "group");
163: boolean visible = false;
164:
165: double yStart = 0;
166: double yEnd = 30;
167: double xEnd = pageWidth;
168:
169: int visibleColumnInfoCount = 0;
170:
171: for (int j = 0; j < columnInfo.getColumnInfos().size(); j++) {
172: ColumnInfo info = columnInfo.getColumnInfos().get(j);
173: if (visibleColumnInfos.contains(info)) {
174: visibleColumnInfoCount++;
175: }
176: }
177:
178: if (visibleColumnInfoCount > 0) {
179: visible = true;
180: int visibleIndex = 0;
181: for (int j = 0; j < columnInfo.getColumnInfos().size(); j++) {
182: ColumnInfo info = columnInfo.getColumnInfos()
183: .get(j);
184:
185: if (visibleColumnInfos.contains(info)) {
186: MessageFieldReportElement groupTitleLabel = ReportElementInfoFactory
187: .getInstance()
188: .getMessageFieldReportElementInfo()
189: .createReportElement();
190: groupTitleLabel.setFormatString(info
191: .getColumnName()
192: + ": $(" + info.getColumnName() + ")");
193: groupTitleLabel.setFont(FontUtils.getFont(
194: layoutStyle.getBaseFontName(),
195: Font.BOLD, 16));
196: if (layoutStyle.getBaseColor() != null) {
197: groupTitleLabel
198: .setBackground(getBackgroundColor(
199: layoutStyle.getBaseColor(),
200: columnGroups.size(), i));
201: }
202: groupTitleLabel.setPosition(new Point2D.Double(
203: xEnd / visibleColumnInfoCount
204: * visibleIndex, yStart));
205: groupTitleLabel
206: .setMinimumSize(new DoubleDimension(
207: xEnd / visibleColumnInfoCount,
208: yEnd - yStart));
209: reportGroupElement.getGroupHeader().addChild(
210: groupTitleLabel);
211: reportGroupElement.getGroupHeader()
212: .setShowInLayoutGUI(true);
213: reportGroupElement.getGroupHeader().setRepeat(
214: true);
215:
216: visibleIndex++;
217: }
218: }
219: }
220:
221: if (!addedToToplevelReportGroups) {
222: reportGroups.addChild(reportGroupElement);
223: addedToToplevelReportGroups = true;
224: } else {
225: parentGroup.addChild(reportGroupElement);
226: }
227:
228: parentGroup = reportGroupElement;
229:
230: if (visible) {
231: tableHeaderPosition = yEnd;
232: } else {
233: tableHeaderPosition = yStart;
234: }
235: tableHeaderBand = reportGroupElement.getGroupHeader();
236: }
237:
238: visibleColumnInfos.removeAll(columnGroups);
239:
240: addTableHeader(tableHeaderPosition, pageWidth, tableHeaderBand,
241: visibleColumnInfos, columnGroups, layoutStyle);
242:
243: BandToplevelReportElement itemBand = addItems(pageWidth,
244: visibleColumnInfos, columnGroups, layoutStyle);
245:
246: //set up functions
247: BandToplevelReportElement reportFooter = ReportElementInfoFactory
248: .getInstance().getBandToplevelReportElementInfo(
249: BandToplevelType.REPORT_FOOTER)
250: .createReportElement();
251:
252: ReportFunctionsElement reportFunctions = ReportElementInfoFactory
253: .getInstance().getReportFunctionsElementInfo()
254: .createReportElement();
255:
256: @Nullable
257: WizardData expressionsWizardData = wizardDatas
258: .get(WizardData.COLUMN_EXPRESSIONS);
259: if (expressionsWizardData != null) {
260: //noinspection unchecked
261: HashMap<ColumnInfo, Class<?>> infos = (HashMap<ColumnInfo, Class<?>>) expressionsWizardData
262: .getValue();
263: for (ColumnInfo columnInfo : infos.keySet()) {
264: ArrayList<ReportElement> children = itemBand
265: .getChildren();
266: for (ReportElement reportElement : children) {
267: if (reportElement instanceof TextFieldReportElement) {
268: TextFieldReportElement textFieldReportElement = (TextFieldReportElement) reportElement;
269: if (textFieldReportElement.getFieldName()
270: .equals(columnInfo.getColumnName())) {
271: @Nullable
272: Class<?> expressionInfo = infos
273: .get(columnInfo);
274: ReportFunctionElement functionElement;
275: try {
276: functionElement = ExpressionRegistry
277: .getInstance()
278: .createWrapperInstance(
279: (Expression) expressionInfo
280: .newInstance());
281: } catch (InstantiationException e) {
282: throw new LayoutException(
283: "Expression not accessible", e);
284: } catch (IllegalAccessException e) {
285: throw new LayoutException(
286: "Expression not accessible", e);
287: }
288: //ReportFunctionElement functionElement = ReportElementInfoFactory.getInstance().getReportFunctionElementInfo(expressionInfo.getClassname()).createReportElement();
289: String name = functionElement
290: .getClass()
291: .getName()
292: .substring(
293: functionElement.getClass()
294: .getName()
295: .lastIndexOf('.') + 1);
296: functionElement.setName(name);
297: try {
298: String groupName = "default";//NON-NLS
299: if (parentGroup != null) {
300: groupName = parentGroup.getName();
301: }
302: functionElement.getClass().getMethod(
303: "setGroup", String.class)
304: .invoke(functionElement,
305: groupName);//NON-NLS
306: } catch (NoSuchMethodException e) {
307: if (LOG.isLoggable(Level.FINE))
308: LOG
309: .log(
310: Level.FINE,
311: "ReportFactory.createReport ",
312: e);
313: //ok
314: } catch (IllegalAccessException e) {
315: if (LOG.isLoggable(Level.FINE))
316: LOG
317: .log(
318: Level.FINE,
319: "StructuredLayoutPlugin.addVisualReportElements ",
320: e);
321: throw new LayoutException(
322: "Method not accessible", e);
323: } catch (InvocationTargetException e) {
324: if (LOG.isLoggable(Level.FINE))
325: LOG
326: .log(
327: Level.FINE,
328: "StructuredLayoutPlugin.addVisualReportElements ",
329: e);
330: throw new LayoutException(
331: "Unexpected error", e);
332: }
333:
334: try {
335: functionElement
336: .getClass()
337: .getMethod("setField",
338: String.class)
339: .invoke(
340: functionElement,
341: columnInfo
342: .getColumnName());//NON-NLS
343: } catch (NoSuchMethodException e) {
344: if (LOG.isLoggable(Level.FINE))
345: LOG
346: .log(
347: Level.FINE,
348: "ReportFactory.createReport ",
349: e);
350: //ok
351: } catch (IllegalAccessException e) {
352: if (LOG.isLoggable(Level.FINE))
353: LOG
354: .log(
355: Level.FINE,
356: "StructuredLayoutPlugin.addVisualReportElements ",
357: e);
358: throw new LayoutException(
359: "Method not accessible", e);
360: } catch (InvocationTargetException e) {
361: if (LOG.isLoggable(Level.FINE))
362: LOG
363: .log(
364: Level.FINE,
365: "StructuredLayoutPlugin.addVisualReportElements ",
366: e);
367: throw new LayoutException(
368: "Unexpected error", e);
369: }
370:
371: TextFieldReportElement columnValueTextField = ReportElementInfoFactory
372: .getInstance()
373: .getTextFieldReportElementInfo()
374: .createReportElement();
375: columnValueTextField.setFieldName(name);
376: columnValueTextField.setFont(FontUtils
377: .getFont(layoutStyle
378: .getBaseFontName(),
379: Font.PLAIN, 12));
380: if (layoutStyle.getBaseColor() != null) {
381: columnValueTextField
382: .setBackground(getBackgroundColor(
383: layoutStyle
384: .getBaseColor(),
385: columnGroups.size(),
386: columnGroups.size() + 2));
387: }
388: columnValueTextField
389: .setMinimumSize(new DoubleDimension(
390: textFieldReportElement
391: .getMinimumSize()
392: .getWidth(), 16));
393: double yOff = 0;
394: columnValueTextField
395: .setPosition(new Point2D.Double(
396: textFieldReportElement
397: .getPosition()
398: .getX(), yOff));
399:
400: if (parentGroup != null) {
401: parentGroup.getGroupFooter().addChild(
402: columnValueTextField);
403: parentGroup.getGroupFooter()
404: .setShowInLayoutGUI(true);
405: parentGroup
406: .getGroupFooter()
407: .setMinimumSize(
408: new DoubleDimension(
409: 0,
410: columnValueTextField
411: .getMinimumSize()
412: .getHeight() + 20));
413: } else {
414: reportFooter
415: .addChild(columnValueTextField);
416: }
417:
418: reportFunctions.addChild(functionElement);
419: }
420: }
421: }
422: }
423: }
424:
425: BandToplevelReportElement pageHeaderBand = ReportElementInfoFactory
426: .getInstance().getBandToplevelReportElementInfo(
427: BandToplevelType.PAGE_HEADER)
428: .createReportElement();
429: BandToplevelReportElement pageFooterBand = ReportElementInfoFactory
430: .getInstance().getBandToplevelReportElementInfo(
431: BandToplevelType.PAGE_FOOTER)
432: .createReportElement();
433:
434: composePageHeader(reportFunctions, pageWidth, pageHeaderBand);
435: composePageFooter(reportFunctions, pageWidth, pageFooterBand);
436:
437: report.addChild(reportFunctions);
438: report.addChild(reportHeaderBand);
439: report.addChild(reportFooter);
440: report.addChild(pageHeaderBand);
441: report.addChild(pageFooterBand);
442: report.addChild(itemBand);
443: report.addChild(ReportElementInfoFactory.getInstance()
444: .getBandToplevelReportElementInfo(
445: BandToplevelType.WATERMARK)
446: .createReportElement());
447: report.addChild(ReportElementInfoFactory.getInstance()
448: .getBandToplevelReportElementInfo(
449: BandToplevelType.NO_DATA_BAND)
450: .createReportElement());
451: report.addChild(reportGroups);
452: report.setPageDefinition(pageDefinition);
453:
454: tableHeaderBand.getVerticalLinealModel().addGuidLine(
455: new GuideLine(tableHeaderPosition, true));
456:
457: ArrayList<ColumnInfo> remainingCoumnInfos = new ArrayList<ColumnInfo>(
458: visibleColumnInfos);
459: for (GroupInfo groupInfo : columnGroups) {
460: remainingCoumnInfos.removeAll(groupInfo.getColumnInfos());
461: }
462:
463: for (int i = 1; i < remainingCoumnInfos.size(); i++) {
464: report.getHorizontalLinealModel().addGuidLine(
465: new GuideLine(pageWidth
466: / (double) remainingCoumnInfos.size() * i,
467: true));
468: }
469: }
470:
471: private void addTableHeader(double tableHeaderPosition,
472: double pageWidth, @NotNull
473: BandToplevelReportElement tableHeaderBand, @NotNull
474: ArrayList<ColumnInfo> visibleColumnInfos, @NotNull
475: ArrayList<GroupInfo> columnGroups, @NotNull
476: LayoutStyle layoutStyle) {
477: ArrayList<ColumnInfo> remainingCoumnInfos = new ArrayList<ColumnInfo>(
478: visibleColumnInfos);
479: for (GroupInfo groupInfo : columnGroups) {
480: remainingCoumnInfos.removeAll(groupInfo.getColumnInfos());
481: }
482:
483: if (remainingCoumnInfos.isEmpty()) {
484: return;
485: }
486:
487: double xStart = 0;
488: double columnWidth = pageWidth / remainingCoumnInfos.size();
489:
490: for (ColumnInfo columnInfo : remainingCoumnInfos) {
491: LabelReportElement columnTitleLabel = ReportElementInfoFactory
492: .getInstance().getLabelReportElementInfo()
493: .createReportElement();
494: columnTitleLabel.setText(columnInfo.getColumnName());
495: columnTitleLabel.setFont(FontUtils.getFont(layoutStyle
496: .getBaseFontName(), Font.BOLD, 12));
497: Color baseColor = layoutStyle.getBaseColor();
498: if (baseColor != null) {
499: columnTitleLabel.setBackground(getBackgroundColor(
500: baseColor, columnGroups.size(), columnGroups
501: .size() + 1));
502: }
503: double xOff = 0;
504: double yOff = 0;
505: columnTitleLabel.setMinimumSize(new DoubleDimension(
506: columnWidth, 16));
507: columnTitleLabel.setPosition(new Point2D.Double(xStart
508: + xOff, tableHeaderPosition + yOff));
509: tableHeaderBand.addChild(columnTitleLabel);
510: tableHeaderBand.setShowInLayoutGUI(true);
511:
512: xStart += columnWidth + xOff;
513: }
514: }
515:
516: @NotNull
517: private BandToplevelReportElement addItems(double pageWidth,
518: @NotNull
519: ArrayList<ColumnInfo> visibleColumnInfos, @NotNull
520: ArrayList<GroupInfo> columnGroups, @NotNull
521: LayoutStyle layoutStyle) {
522: ArrayList<ColumnInfo> remainingCoumnInfos = new ArrayList<ColumnInfo>(
523: visibleColumnInfos);
524: for (GroupInfo groupInfo : columnGroups) {
525: remainingCoumnInfos.removeAll(groupInfo.getColumnInfos());
526: }
527:
528: BandToplevelReportElement itemBand = ReportElementInfoFactory
529: .getInstance().getBandToplevelReportElementInfo(
530: BandToplevelType.ITEM_BAND)
531: .createReportElement();
532:
533: double xStart = 0;
534: double columnWidth = pageWidth / remainingCoumnInfos.size();
535: double tableHeaderPosition = 0;
536:
537: for (ColumnInfo columnInfo : remainingCoumnInfos) {
538: TextFieldReportElement columnValueTextField = ReportElementInfoFactory
539: .getInstance().getTextFieldReportElementInfo()
540: .createReportElement();
541: columnValueTextField.setFieldName(columnInfo
542: .getColumnName());
543: columnValueTextField.setFont(FontUtils.getFont(layoutStyle
544: .getBaseFontName(), Font.PLAIN, 12));
545: Color baseColor = layoutStyle.getBaseColor();
546: if (baseColor != null) {
547: columnValueTextField.setBackground(getBackgroundColor(
548: baseColor, columnGroups.size(), columnGroups
549: .size() + 2));
550: }
551: double xOff = 0;
552: double yOff = 0;
553: columnValueTextField.setMinimumSize(new DoubleDimension(
554: columnWidth, 16));
555: columnValueTextField.setPosition(new Point2D.Double(xStart
556: + xOff, tableHeaderPosition + yOff));
557: itemBand.addChild(columnValueTextField);
558:
559: xStart += columnWidth + xOff;
560: }
561: return itemBand;
562: }
563: }
|