0001: /*
0002: * Copyright 2006-2007 Pentaho Corporation. All rights reserved.
0003: * This software was developed by Pentaho Corporation and is provided under the terms
0004: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
0005: * this file except in compliance with the license. If you need a copy of the license,
0006: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt.
0007: *
0008: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
0009: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
0010: * the license for the specific language governing your rights and limitations.
0011: *
0012: * Additional Contributor(s): Martin Schmid gridvision engineering GmbH
0013: */
0014: package org.pentaho.reportdesigner.crm.report.datasetplugin.multidataset;
0015:
0016: import com.jgoodies.forms.layout.CellConstraints;
0017: import com.jgoodies.forms.layout.FormLayout;
0018: import org.gjt.xpp.XmlPullNode;
0019: import org.jetbrains.annotations.NonNls;
0020: import org.jetbrains.annotations.NotNull;
0021: import org.jetbrains.annotations.Nullable;
0022: import org.pentaho.core.admin.datasources.DataSourceInfo;
0023: import org.pentaho.core.admin.datasources.StandaloneSimpleJNDIDatasourceAdmin;
0024: import org.pentaho.core.session.StandaloneSession;
0025: import org.pentaho.jfreereport.wizard.ReportWizard;
0026: import org.pentaho.reportdesigner.crm.report.PropertyKeys;
0027: import org.pentaho.reportdesigner.crm.report.ReportDialog;
0028: import org.pentaho.reportdesigner.crm.report.ReportDialogConstants;
0029: import org.pentaho.reportdesigner.crm.report.connection.ColumnInfo;
0030: import org.pentaho.reportdesigner.crm.report.datasetplugin.ColumnInfoTableModel;
0031: import org.pentaho.reportdesigner.crm.report.datasetplugin.DataFetchException;
0032: import org.pentaho.reportdesigner.crm.report.datasetplugin.MetadataTableModel;
0033: import org.pentaho.reportdesigner.crm.report.model.DateFieldReportElement;
0034: import org.pentaho.reportdesigner.crm.report.model.NumberFieldReportElement;
0035: import org.pentaho.reportdesigner.crm.report.model.Report;
0036: import org.pentaho.reportdesigner.crm.report.model.ReportElement;
0037: import org.pentaho.reportdesigner.crm.report.model.TextFieldReportElement;
0038: import org.pentaho.reportdesigner.crm.report.model.dataset.TableModelDataSetReportElement;
0039: import org.pentaho.reportdesigner.crm.report.model.functions.ExpressionRegistry;
0040: import org.pentaho.reportdesigner.crm.report.reportelementinfo.ReportElementInfoFactory;
0041: import org.pentaho.reportdesigner.crm.report.reportexporter.ReportCreationException;
0042: import org.pentaho.reportdesigner.crm.report.reportexporter.ReportVisitor;
0043: import org.pentaho.reportdesigner.crm.report.settings.WorkspaceSettings;
0044: import org.pentaho.reportdesigner.crm.report.util.FileRelativator;
0045: import org.pentaho.reportdesigner.lib.client.i18n.TranslationManager;
0046: import org.pentaho.reportdesigner.lib.client.undo.Undo;
0047: import org.pentaho.reportdesigner.lib.client.undo.UndoEntry;
0048: import org.pentaho.reportdesigner.lib.client.util.DoubleDimension;
0049: import org.pentaho.reportdesigner.lib.common.xml.XMLConstants;
0050: import org.pentaho.reportdesigner.lib.common.xml.XMLContext;
0051: import org.pentaho.reportdesigner.lib.common.xml.XMLUtils;
0052: import org.pentaho.reportdesigner.lib.common.xml.XMLWriter;
0053: import org.pentaho.util.logging.ILogger;
0054:
0055: import javax.swing.*;
0056: import javax.swing.table.DefaultTableModel;
0057: import javax.swing.table.TableModel;
0058: import javax.xml.xpath.XPathExpressionException;
0059: import java.awt.*;
0060: import java.awt.datatransfer.DataFlavor;
0061: import java.awt.datatransfer.Transferable;
0062: import java.awt.datatransfer.UnsupportedFlavorException;
0063: import java.awt.dnd.DnDConstants;
0064: import java.awt.font.FontRenderContext;
0065: import java.awt.geom.Rectangle2D;
0066: import java.io.File;
0067: import java.io.IOException;
0068: import java.net.MalformedURLException;
0069: import java.text.DecimalFormat;
0070: import java.text.SimpleDateFormat;
0071: import java.util.ArrayList;
0072: import java.util.Date;
0073: import java.util.HashSet;
0074: import java.util.Locale;
0075: import java.util.Map;
0076: import java.util.logging.Level;
0077: import java.util.logging.Logger;
0078:
0079: /**
0080: * User: Martin Date: 31.01.2006 Time: 10:30:43
0081: */
0082: public class MultiDataSetReportElement extends
0083: TableModelDataSetReportElement {
0084: @NonNls
0085: @NotNull
0086: private static final Logger LOG = Logger
0087: .getLogger(MultiDataSetReportElement.class.getName());
0088:
0089: public enum ConnectionType {
0090: @NotNull
0091: JNDI, @NotNull
0092: MQL, @NotNull
0093: XQuery
0094: }
0095:
0096: @NotNull
0097: private ConnectionType connectionType;
0098:
0099: @NotNull
0100: private ArrayList<JNDISource> jndiSources;
0101: @Nullable
0102: private String xQueryDataFile;
0103:
0104: @Nullable
0105: private JNDISource selectedJNDIDataSource;
0106:
0107: private boolean useMondrianCubeDefinition;
0108: @NotNull
0109: private String mondrianCubeDefinitionFile;
0110: @Nullable
0111: private String xmiDefinitionFile;
0112: @NotNull
0113: private ArrayList<Query> queries;
0114:
0115: @NotNull
0116: private ArrayList<ColumnInfo> columnInfos;
0117:
0118: @Nullable
0119: private TableModel cachedTableModel;
0120: @NotNull
0121: private JTable infoTable;
0122:
0123: private boolean limitPreviewRows;
0124: private int maxPreviewRows;
0125:
0126: public MultiDataSetReportElement() {
0127: connectionType = ConnectionType.JNDI;
0128: jndiSources = new ArrayList<JNDISource>();
0129:
0130: StandaloneSession session = new StandaloneSession(
0131: "Datasource-Session"); //$NON-NLS-1$
0132: session.setLoggingLevel(ILogger.ERROR);
0133: StandaloneSimpleJNDIDatasourceAdmin dataSourceAdmin = new StandaloneSimpleJNDIDatasourceAdmin(
0134: ReportWizard.simpleJNDIPath, session);//NON-NLS
0135: //noinspection unchecked
0136: Map<String, DataSourceInfo> dsMap = dataSourceAdmin
0137: .listDataSources();
0138: for (Object o : dsMap.keySet()) {
0139: String key = (String) o;
0140: DataSourceInfo dsi = dsMap.get(key);
0141:
0142: JNDISource jndiSource = new JNDISource();
0143: jndiSource.setJndiName(dsi.getName());
0144: jndiSource.setDriverClass(dsi.getDriver());
0145: jndiSource.setConnectionString(dsi.getUrl());
0146: jndiSource.setUsername(dsi.getUserId());
0147: jndiSource.setPassword(dsi.getPassword());
0148:
0149: jndiSources.add(jndiSource);
0150: }
0151:
0152: if (jndiSources.isEmpty()) {
0153: jndiSources.add(new JNDISource("SampleData",
0154: "org.hsqldb.jdbcDriver",
0155: "jdbc:hsqldb:hsql://localhost/sampledata",
0156: "pentaho_user", "password"));// NON-NLS
0157: jndiSources.add(new JNDISource("Quartz",
0158: "org.hsqldb.jdbcDriver",
0159: "jdbc:hsqldb:hsql://localhost/quartz",
0160: "pentaho_user", "password"));// NON-NLS
0161: jndiSources.add(new JNDISource("Hibernate",
0162: "org.hsqldb.jdbcDriver",
0163: "jdbc:hsqldb:hsql://localhost/hibernate",
0164: "hibuser", "password"));// NON-NLS
0165: jndiSources.add(new JNDISource("Shark",
0166: "org.hsqldb.jdbcDriver",
0167: "jdbc:hsqldb:hsql://localhost/shark", "sa", ""));// NON-NLS
0168: }
0169:
0170: xQueryDataFile = "";
0171: mondrianCubeDefinitionFile = "";
0172:
0173: selectedJNDIDataSource = null;
0174: useMondrianCubeDefinition = false;
0175: queries = new ArrayList<Query>();
0176: queries.add(new Query(
0177: ReportDialogConstants.DEFAULT_DATA_FACTORY, ""));
0178: columnInfos = new ArrayList<ColumnInfo>();
0179:
0180: infoTable = new JTable(0, 0);
0181:
0182: limitPreviewRows = true;
0183: maxPreviewRows = 10000;
0184: }
0185:
0186: @NotNull
0187: public String getQueryName() {
0188: if (!queries.isEmpty()) {
0189: return queries.get(0).getQueryName();
0190: }
0191: return "";
0192: }
0193:
0194: @NotNull
0195: public ConnectionType getConnectionType() {
0196: return connectionType;
0197: }
0198:
0199: public void setConnectionType(@NotNull
0200: final ConnectionType connectionType) {
0201: // noinspection ConstantConditions
0202: if (connectionType == null) {
0203: throw new IllegalArgumentException(
0204: "connectionType must not be null");
0205: }
0206:
0207: final ConnectionType oldConnectionType = this .connectionType;
0208: this .connectionType = connectionType;
0209:
0210: Undo undo = getUndo();
0211: if (undo != null && !undo.isInProgress()) {
0212: undo.startTransaction(PropertyKeys.CONNECTION_TYPE);
0213: undo.add(new UndoEntry() {
0214: public void undo() {
0215: setConnectionType(oldConnectionType);
0216: }
0217:
0218: public void redo() {
0219: setConnectionType(connectionType);
0220: }
0221: });
0222: undo.endTransaction();
0223: }
0224:
0225: cachedTableModel = null;
0226:
0227: firePropertyChange(PropertyKeys.CONNECTION_TYPE,
0228: oldConnectionType, connectionType);
0229: }
0230:
0231: @NotNull
0232: public ArrayList<JNDISource> getJndiSources() {
0233: return new ArrayList<JNDISource>(jndiSources);
0234: }
0235:
0236: public void setJndiSources(@NotNull
0237: final ArrayList<JNDISource> jndiSources) {
0238: // noinspection ConstantConditions
0239: if (jndiSources == null) {
0240: throw new IllegalArgumentException(
0241: "jndiSources must not be null");
0242: }
0243:
0244: final ArrayList<JNDISource> oldJndiSources = this .jndiSources;
0245: this .jndiSources = jndiSources;
0246:
0247: Undo undo = getUndo();
0248: if (undo != null && !undo.isInProgress()) {
0249: undo.startTransaction(PropertyKeys.JNDI_SOURCES);
0250: undo.add(new UndoEntry() {
0251: public void undo() {
0252: setJndiSources(oldJndiSources);
0253: }
0254:
0255: public void redo() {
0256: setJndiSources(jndiSources);
0257: }
0258: });
0259: undo.endTransaction();
0260: }
0261:
0262: cachedTableModel = null;
0263:
0264: ArrayList<String> sources = new ArrayList<String>();
0265: for (JNDISource jndiSource : jndiSources) {
0266: sources.add(jndiSource.getJndiName() + "|"
0267: + jndiSource.getDriverClass() + "|"
0268: + jndiSource.getConnectionString() + "|"
0269: + jndiSource.getUsername() + "|"
0270: + jndiSource.getPassword());
0271: }
0272:
0273: WorkspaceSettings.getInstance().put("JNDISources", sources);
0274:
0275: firePropertyChange(PropertyKeys.JNDI_SOURCES, oldJndiSources,
0276: jndiSources);
0277: }
0278:
0279: @NotNull
0280: public String getMondrianCubeDefinitionFile() {
0281: return mondrianCubeDefinitionFile;
0282: }
0283:
0284: public void setMondrianCubeDefinitionFile(@NotNull
0285: final String mondrianCubeDefinitionFile) {
0286: // noinspection ConstantConditions
0287: if (mondrianCubeDefinitionFile == null) {
0288: throw new IllegalArgumentException(
0289: "mondrianCubeDefinitionFile must not be null");
0290: }
0291:
0292: final String oldMondrianCubeDefinitionFile = this .mondrianCubeDefinitionFile;
0293: this .mondrianCubeDefinitionFile = mondrianCubeDefinitionFile;
0294:
0295: Undo undo = getUndo();
0296: if (undo != null && !undo.isInProgress()) {
0297: undo
0298: .startTransaction(PropertyKeys.MONDRIAN_CUBE_DEFINITION_FILE);
0299: undo.add(new UndoEntry() {
0300: public void undo() {
0301: setMondrianCubeDefinitionFile(oldMondrianCubeDefinitionFile);
0302: }
0303:
0304: public void redo() {
0305: setMondrianCubeDefinitionFile(mondrianCubeDefinitionFile);
0306: }
0307: });
0308: undo.endTransaction();
0309: }
0310:
0311: cachedTableModel = null;
0312:
0313: firePropertyChange(PropertyKeys.MONDRIAN_CUBE_DEFINITION_FILE,
0314: oldMondrianCubeDefinitionFile,
0315: mondrianCubeDefinitionFile);
0316: }
0317:
0318: @NotNull
0319: public ArrayList<Query> getQueries() {
0320: ArrayList<Query> copyQueries = new ArrayList<Query>();
0321: for (Query query : queries) {
0322: copyQueries.add(new Query(query.getQueryName(), query
0323: .getQuery()));
0324: }
0325: return copyQueries;
0326: }
0327:
0328: public void setQueries(@NotNull
0329: final ArrayList<Query> queries) {
0330: // noinspection ConstantConditions
0331: if (queries == null) {
0332: throw new IllegalArgumentException(
0333: "queries must not be null");
0334: }
0335: if (queries.size() < 1) {
0336: throw new IllegalArgumentException(
0337: "queries must contain at least one query (mainquery)");
0338: }
0339:
0340: final ArrayList<Query> oldQueries = this .queries;
0341: this .queries = queries;
0342:
0343: Undo undo = getUndo();
0344: if (undo != null && !undo.isInProgress()) {
0345: undo.startTransaction(PropertyKeys.QUERIES);
0346: undo.add(new UndoEntry() {
0347: public void undo() {
0348: setQueries(oldQueries);
0349: }
0350:
0351: public void redo() {
0352: setQueries(queries);
0353: }
0354: });
0355: undo.endTransaction();
0356: }
0357:
0358: cachedTableModel = null;
0359:
0360: firePropertyChange(PropertyKeys.QUERIES, oldQueries, queries);
0361: }
0362:
0363: public boolean isLimitPreviewRows() {
0364: return limitPreviewRows;
0365: }
0366:
0367: public int getMaxPreviewRows() {
0368: return maxPreviewRows;
0369: }
0370:
0371: public void setLimitPreviewRows(final boolean limitPreviewRows) {
0372: final boolean oldLimitPreviewRows = this .limitPreviewRows;
0373: this .limitPreviewRows = limitPreviewRows;
0374:
0375: Undo undo = getUndo();
0376: if (undo != null && !undo.isInProgress()) {
0377: undo.startTransaction(PropertyKeys.LIMIT_PREVIEW_ROWS);
0378: undo.add(new UndoEntry() {
0379: public void undo() {
0380: setLimitPreviewRows(oldLimitPreviewRows);
0381: }
0382:
0383: public void redo() {
0384: setLimitPreviewRows(limitPreviewRows);
0385: }
0386: });
0387: undo.endTransaction();
0388: }
0389:
0390: firePropertyChange(PropertyKeys.LIMIT_PREVIEW_ROWS,
0391: oldLimitPreviewRows, limitPreviewRows);
0392: }
0393:
0394: public void setMaxPreviewRows(final int maxPreviewRows) {
0395: final int oldMaxPreviewRows = this .maxPreviewRows;
0396: this .maxPreviewRows = maxPreviewRows;
0397:
0398: Undo undo = getUndo();
0399: if (undo != null && !undo.isInProgress()) {
0400: undo.startTransaction(PropertyKeys.MAX_PREVIEW_ROWS);
0401: undo.add(new UndoEntry() {
0402: public void undo() {
0403: setMaxPreviewRows(oldMaxPreviewRows);
0404: }
0405:
0406: public void redo() {
0407: setMaxPreviewRows(maxPreviewRows);
0408: }
0409: });
0410: undo.endTransaction();
0411: }
0412:
0413: firePropertyChange(PropertyKeys.MAX_PREVIEW_ROWS,
0414: oldMaxPreviewRows, maxPreviewRows);
0415: }
0416:
0417: @Nullable
0418: public JNDISource getSelectedJNDIDataSource() {
0419: return selectedJNDIDataSource;
0420: }
0421:
0422: public void setSelectedJNDIDataSource(@Nullable
0423: final JNDISource selectedJNDIDataSource) {
0424: final JNDISource oldSelectedJNJndiSource = this .selectedJNDIDataSource;
0425: this .selectedJNDIDataSource = selectedJNDIDataSource;
0426:
0427: Undo undo = getUndo();
0428: if (undo != null && !undo.isInProgress()) {
0429: undo
0430: .startTransaction(PropertyKeys.SELECTED_JNDI_DATA_SOURCE);
0431: undo.add(new UndoEntry() {
0432: public void undo() {
0433: setSelectedJNDIDataSource(oldSelectedJNJndiSource);
0434: }
0435:
0436: public void redo() {
0437: setSelectedJNDIDataSource(selectedJNDIDataSource);
0438: }
0439: });
0440: undo.endTransaction();
0441: }
0442:
0443: cachedTableModel = null;
0444:
0445: firePropertyChange(PropertyKeys.SELECTED_JNDI_DATA_SOURCE,
0446: oldSelectedJNJndiSource, selectedJNDIDataSource);
0447: }
0448:
0449: public boolean isUseMondrianCubeDefinition() {
0450: return useMondrianCubeDefinition;
0451: }
0452:
0453: public void setUseMondrianCubeDefinition(
0454: final boolean useMondrianCubeDefinition) {
0455: final boolean oldUseMondrianCubeDefinition = this .useMondrianCubeDefinition;
0456: this .useMondrianCubeDefinition = useMondrianCubeDefinition;
0457:
0458: Undo undo = getUndo();
0459: if (undo != null && !undo.isInProgress()) {
0460: undo
0461: .startTransaction(PropertyKeys.USE_MONDRIAN_CUBE_DEFINITION);
0462: undo.add(new UndoEntry() {
0463: public void undo() {
0464: setUseMondrianCubeDefinition(oldUseMondrianCubeDefinition);
0465: }
0466:
0467: public void redo() {
0468: setUseMondrianCubeDefinition(useMondrianCubeDefinition);
0469: }
0470: });
0471: undo.endTransaction();
0472: }
0473:
0474: cachedTableModel = null;
0475:
0476: firePropertyChange(PropertyKeys.USE_MONDRIAN_CUBE_DEFINITION,
0477: oldUseMondrianCubeDefinition, useMondrianCubeDefinition);
0478: }
0479:
0480: @Nullable
0481: public String getXQueryDataFile() {
0482: return xQueryDataFile;
0483: }
0484:
0485: public void setXQueryDataFile(@Nullable
0486: final String xQueryDataFile) {
0487: final String oldXQueryDataFile = this .xQueryDataFile;
0488: this .xQueryDataFile = xQueryDataFile;
0489:
0490: Undo undo = getUndo();
0491: if (undo != null && !undo.isInProgress()) {
0492: undo.startTransaction(PropertyKeys.XQUERY_DATA_FILE);
0493: undo.add(new UndoEntry() {
0494: public void undo() {
0495: setXQueryDataFile(oldXQueryDataFile);
0496: }
0497:
0498: public void redo() {
0499: setXQueryDataFile(xQueryDataFile);
0500: }
0501: });
0502: undo.endTransaction();
0503: }
0504:
0505: cachedTableModel = null;
0506:
0507: firePropertyChange(PropertyKeys.XQUERY_DATA_FILE,
0508: oldXQueryDataFile, xQueryDataFile);
0509: }
0510:
0511: @Nullable
0512: public String getXmiDefinitionFile() {
0513: return xmiDefinitionFile;
0514: }
0515:
0516: public void setXmiDefinitionFile(@Nullable
0517: final String xmiDefinitionFile) {
0518: final String oldXmiDefinitionFile = this .xmiDefinitionFile;
0519: this .xmiDefinitionFile = xmiDefinitionFile;
0520:
0521: Undo undo = getUndo();
0522: if (undo != null && !undo.isInProgress()) {
0523: undo.startTransaction(PropertyKeys.XMI_DEFINITION_FILE);
0524: undo.add(new UndoEntry() {
0525: public void undo() {
0526: setXmiDefinitionFile(oldXmiDefinitionFile);
0527: }
0528:
0529: public void redo() {
0530: setXmiDefinitionFile(xmiDefinitionFile);
0531: }
0532: });
0533: undo.endTransaction();
0534: }
0535:
0536: cachedTableModel = null;
0537:
0538: firePropertyChange(PropertyKeys.XMI_DEFINITION_FILE,
0539: oldXmiDefinitionFile, xmiDefinitionFile);
0540: }
0541:
0542: public boolean canCreateReportOnServer() {
0543: return false;
0544: }
0545:
0546: public void createReportOnServer(@NotNull
0547: String jFreeReportDefinition) {
0548: throw new RuntimeException(
0549: "Can not create the report on the server");
0550: }
0551:
0552: public boolean canFetchPreviewDataTableModel() {
0553: return true;
0554: }
0555:
0556: @NotNull
0557: public ArrayList<ColumnInfo> fetchColumnInfos(@NotNull
0558: ConnectionType connectionType, @Nullable
0559: JNDISource source, @Nullable
0560: String xQueryDataFile, @Nullable
0561: String xmiDefinitionFile, boolean useMondrianCubeDefinition,
0562: @Nullable
0563: String mondrianCubeDefinition, @NotNull
0564: String queryString) throws DataFetchException {
0565: MetadataTableModel tableModel = createTableModel(
0566: connectionType, source, xQueryDataFile,
0567: xmiDefinitionFile, useMondrianCubeDefinition,
0568: mondrianCubeDefinition, queryString, true, 1);
0569:
0570: ArrayList<ColumnInfo> columnInfos = new ArrayList<ColumnInfo>();
0571: for (int i = 0; i < tableModel.getColumnCount(); i++) {
0572: columnInfos.add(tableModel.getColumnInfo(i));
0573: }
0574: return columnInfos;
0575: }
0576:
0577: @NotNull
0578: private MetadataTableModel createTableModel(@NotNull
0579: ConnectionType connectionType, @Nullable
0580: JNDISource selectedJNDIDataSource, @Nullable
0581: String xQueryDataFile, @Nullable
0582: String xmiDefinitionFile, boolean useMondrianCubeDefinition,
0583: @Nullable
0584: String mondrianCubeDefinitionFile, @NotNull
0585: String queryString, boolean limitRows, int maxRowsToProcess)
0586: throws DataFetchException {
0587: MetadataTableModel tableModel;
0588:
0589: if (connectionType == ConnectionType.XQuery) {
0590: try {
0591: tableModel = new XPathTableModel(new File(
0592: xQueryDataFile).toURI().toURL(), queryString,
0593: null, limitRows, maxRowsToProcess);
0594: } catch (IOException e) {
0595: throw new DataFetchException(
0596: "Could not read XML data file", e);
0597: } catch (XPathExpressionException e) {
0598: throw new DataFetchException("Invalid query", e);
0599: }
0600: } else if (connectionType == ConnectionType.JNDI) {
0601: if (useMondrianCubeDefinition) {
0602: try {
0603: if (selectedJNDIDataSource == null) {
0604: throw new DataFetchException(
0605: "You have to select a JNDI source");
0606: }
0607: tableModel = new MondrianTableModel(
0608: selectedJNDIDataSource, new File(
0609: mondrianCubeDefinitionFile).toURI()
0610: .toURL(), queryString, limitRows,
0611: maxRowsToProcess);
0612: } catch (MalformedURLException e) {
0613: throw new DataFetchException(
0614: "Could not read XML file", e);
0615: }
0616: } else {
0617: if (selectedJNDIDataSource == null) {
0618: throw new DataFetchException(
0619: "You have to select a JNDI source");
0620: }
0621: try {
0622: tableModel = new JDBCTableModel(
0623: selectedJNDIDataSource, queryString,
0624: maxRowsToProcess);
0625: } catch (Exception e) {
0626: throw new DataFetchException(e.getMessage(), e);
0627: }
0628: }
0629: } else if (connectionType == ConnectionType.MQL) {
0630: if (xmiDefinitionFile == null) {
0631: throw new DataFetchException(
0632: "xmiDefinitionFile must be set");
0633: }
0634: try {
0635: Report report = getReport();
0636: Locale defaultLocale = Locale.getDefault();
0637: if (report != null) {
0638: defaultLocale = report.getDefaultLocale();
0639: }
0640: tableModel = new MQLTableModel(defaultLocale,
0641: xmiDefinitionFile, queryString, limitRows,
0642: maxRowsToProcess);
0643: } catch (Throwable e) {
0644: throw new DataFetchException(e.getMessage(), e);
0645: }
0646: } else {
0647: throw new DataFetchException("Unsupported connection type");
0648: }
0649: return tableModel;
0650: }
0651:
0652: @NotNull
0653: public TableModel fetchPreviewDataTableModel()
0654: throws DataFetchException {
0655: try {
0656: long l1 = System.nanoTime();
0657: TableModel ctm = cachedTableModel;
0658: if (ctm == null) {
0659: if (!queries.isEmpty()) {
0660: ctm = createTableModel(connectionType,
0661: selectedJNDIDataSource, xQueryDataFile,
0662: xmiDefinitionFile,
0663: useMondrianCubeDefinition,
0664: mondrianCubeDefinitionFile, queries.get(0)
0665: .getQuery(), true, 1000);
0666: cachedTableModel = ctm;
0667: } else {
0668: ctm = new DefaultTableModel();
0669: }
0670: }
0671: long l2 = System.nanoTime();
0672: if (LOG.isLoggable(Level.FINE))
0673: LOG.log(Level.FINE,
0674: "MultiDataSetReportElement.fetchPreviewDataTableModel "
0675: + (l2 - l1) / (1000. * 1000.) + " ms");
0676: return ctm;
0677: } catch (Throwable e) {
0678: throw new DataFetchException(e);
0679: }
0680: }
0681:
0682: public boolean canFetchRealDataTableModel() {
0683: return true;
0684: }
0685:
0686: @NotNull
0687: public TableModel fetchRealDataTableModel()
0688: throws DataFetchException {
0689: try {
0690: String query = queries.get(0).getQuery();
0691: return createTableModel(connectionType,
0692: selectedJNDIDataSource, xQueryDataFile,
0693: xmiDefinitionFile, useMondrianCubeDefinition,
0694: mondrianCubeDefinitionFile, query, false,
0695: Integer.MAX_VALUE);
0696: } catch (Throwable e) {
0697: throw new DataFetchException(e);
0698: }
0699: }
0700:
0701: @NotNull
0702: public String getShortSummary() {
0703: if (connectionType == ConnectionType.JNDI) {
0704: JNDISource jndiDataSource = selectedJNDIDataSource;
0705: if (useMondrianCubeDefinition) {
0706: if (jndiDataSource != null) {
0707: return getQueryName()
0708: + " "
0709: + TranslationManager
0710: .getInstance()
0711: .getTranslation(
0712: "R",
0713: "MultiDataSetReportElement.Mondrian",
0714: mondrianCubeDefinitionFile,
0715: jndiDataSource
0716: .getJndiName());
0717: } else {
0718: return getQueryName()
0719: + " "
0720: + TranslationManager
0721: .getInstance()
0722: .getTranslation(
0723: "R",
0724: "MultiDataSetReportElement.Mondrian",
0725: mondrianCubeDefinitionFile,
0726: TranslationManager
0727: .getInstance()
0728: .getTranslation(
0729: "R",
0730: "MultiDataSetReportElement.Undefined"));
0731: }
0732: } else {
0733: if (jndiDataSource != null) {
0734: return getQueryName()
0735: + " "
0736: + TranslationManager
0737: .getInstance()
0738: .getTranslation(
0739: "R",
0740: "MultiDataSetReportElement.JNDI",
0741: jndiDataSource
0742: .getJndiName());
0743: } else {
0744: return getQueryName()
0745: + " "
0746: + TranslationManager
0747: .getInstance()
0748: .getTranslation(
0749: "R",
0750: "MultiDataSetReportElement.JNDI",
0751: TranslationManager
0752: .getInstance()
0753: .getTranslation(
0754: "R",
0755: "MultiDataSetReportElement.Undefined"));
0756: }
0757: }
0758:
0759: } else if (connectionType == ConnectionType.XQuery) {
0760: String xQueryDataFile = this .xQueryDataFile;
0761: if (xQueryDataFile != null) {
0762: return getQueryName()
0763: + " "
0764: + TranslationManager
0765: .getInstance()
0766: .getTranslation(
0767: "R",
0768: "MultiDataSetReportElement.XQuery",
0769: xQueryDataFile);
0770: } else {
0771: return getQueryName()
0772: + " "
0773: + TranslationManager
0774: .getInstance()
0775: .getTranslation(
0776: "R",
0777: "MultiDataSetReportElement.XQuery",
0778: "");
0779: }
0780: } else if (connectionType == ConnectionType.MQL) {
0781: String xmiDefinitionFile = this .xmiDefinitionFile;
0782: if (xmiDefinitionFile != null) {
0783: return getQueryName()
0784: + " "
0785: + TranslationManager
0786: .getInstance()
0787: .getTranslation(
0788: "R",
0789: "MultiDataSetReportElement.MQL",
0790: xmiDefinitionFile);
0791: } else {
0792: return getQueryName()
0793: + " "
0794: + TranslationManager
0795: .getInstance()
0796: .getTranslation(
0797: "R",
0798: "MultiDataSetReportElement.MQL",
0799: "");
0800: }
0801: }
0802: return getQueryName();
0803: }
0804:
0805: @NotNull
0806: public HashSet<String> getDefinedFields() {
0807: HashSet<String> definedFields = new HashSet<String>();
0808: for (ColumnInfo columnInfo : columnInfos) {
0809: definedFields.add(columnInfo.getColumnName());
0810: }
0811: return definedFields;
0812: }
0813:
0814: public boolean canConfigure() {
0815: return true;
0816: }
0817:
0818: public boolean showConfigurationComponent(@NotNull
0819: ReportDialog parent, boolean firsttime) {
0820: boolean ok = MultiDataSetReportElementConfigurator
0821: .showStaticFactoryDataSetReportElementConfigurator(
0822: parent, this );
0823: cachedTableModel = null;
0824: return ok;
0825: }
0826:
0827: @NotNull
0828: public JComponent getInfoComponent() {
0829: @NonNls
0830: FormLayout formLayout = new FormLayout(
0831: "2dlu, pref, 4dlu, 0dlu:grow, 2dlu",
0832: "2dlu, pref, 4dlu, pref, 4dlu, fill:default:grow, 2dlu");
0833: JPanel infoPanel = new JPanel(formLayout);
0834: @NonNls
0835: CellConstraints cc = new CellConstraints();
0836:
0837: infoTable = new JTable(new ColumnInfoTableModel(columnInfos));
0838: infoTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
0839:
0840: if (ReportDialogConstants.DEFAULT_DATA_FACTORY
0841: .equals(getQueryName())) {
0842: initDragAndDrop(infoTable);
0843: } else {
0844: infoTable.setEnabled(false);
0845: }
0846:
0847: infoPanel.add(new JScrollPane(infoTable), cc.xyw(2, 6, 3,
0848: "fill, fill"));
0849:
0850: return infoPanel;
0851: }
0852:
0853: @NotNull
0854: public ArrayList<ColumnInfo> getColumnInfos() {
0855: return columnInfos;
0856: }
0857:
0858: public void setColumnInfos(@NotNull
0859: final ArrayList<ColumnInfo> columnInfos) {
0860: // noinspection ConstantConditions
0861: if (columnInfos == null) {
0862: throw new IllegalArgumentException(
0863: "columnInfos must not be null");
0864: }
0865:
0866: final ArrayList<ColumnInfo> oldColumnInfos = this .columnInfos;
0867: this .columnInfos = columnInfos;
0868:
0869: infoTable.setModel(new ColumnInfoTableModel(columnInfos));
0870:
0871: Undo undo = getUndo();
0872: if (undo != null && !undo.isInProgress()) {
0873: undo.startTransaction(PropertyKeys.COLUMN_INFOS);
0874: undo.add(new UndoEntry() {
0875: public void undo() {
0876: setColumnInfos(oldColumnInfos);
0877: }
0878:
0879: public void redo() {
0880: setColumnInfos(columnInfos);
0881: }
0882: });
0883: undo.endTransaction();
0884: }
0885: firePropertyChange(PropertyKeys.COLUMN_INFOS, oldColumnInfos,
0886: columnInfos);
0887: }
0888:
0889: private void initDragAndDrop(@NotNull
0890: final JTable table) {
0891: @NonNls
0892: final DataFlavor dataFlavorLibraryItems = new DataFlavor(
0893: "application/x-icore-reportelement;class="
0894: + ReportElement.class.getName(),
0895: "ReportElement " + ReportDialogConstants.UNSELECTED);
0896:
0897: table.setTransferHandler(new TransferHandler() {
0898: @NotNull
0899: protected Transferable createTransferable(@NotNull
0900: JComponent c) {
0901: int selectedRow = table.getSelectedRow();
0902: ColumnInfo columnInfo = columnInfos.get(selectedRow);
0903: TextFieldReportElement textFieldReportElement = createReportElement(
0904: columnInfo, new FontRenderContext(null, true,
0905: true));
0906:
0907: final ReportElement reportElement = textFieldReportElement;
0908:
0909: return new Transferable() {
0910: @NotNull
0911: public DataFlavor[] getTransferDataFlavors() {
0912: return new DataFlavor[] { dataFlavorLibraryItems };
0913: }
0914:
0915: public boolean isDataFlavorSupported(@NotNull
0916: DataFlavor flavor) {
0917: return dataFlavorLibraryItems.equals(flavor);
0918: }
0919:
0920: @NotNull
0921: public Object getTransferData(@NotNull
0922: DataFlavor flavor)
0923: throws UnsupportedFlavorException {
0924: if (dataFlavorLibraryItems.equals(flavor)) {
0925: return reportElement;
0926: } else {
0927: throw new UnsupportedFlavorException(flavor);
0928: }
0929: }
0930: };
0931: }
0932:
0933: public int getSourceActions(@NotNull
0934: JComponent c) {
0935: return DnDConstants.ACTION_COPY;
0936: }
0937: });
0938:
0939: table.setDragEnabled(true);
0940:
0941: }
0942:
0943: @NotNull
0944: private TextFieldReportElement createReportElement(@NotNull
0945: ColumnInfo columnInfo, @NotNull
0946: FontRenderContext fontRenderContext) {
0947: TextFieldReportElement textFieldReportElement;
0948: if (Date.class.isAssignableFrom(columnInfo.getColumnClass())) {
0949: DateFieldReportElement dateFieldReportElement = ReportElementInfoFactory
0950: .getInstance().getDateFieldReportElementInfo()
0951: .createReportElement();
0952: if (columnInfo.getFormat() != null) {
0953: dateFieldReportElement.setFormat(new SimpleDateFormat(
0954: columnInfo.getFormat()));
0955: }
0956:
0957: textFieldReportElement = dateFieldReportElement;
0958: } else if (Number.class.isAssignableFrom(columnInfo
0959: .getColumnClass())) {
0960: NumberFieldReportElement numberFieldReportElement = ReportElementInfoFactory
0961: .getInstance().getNumberFieldReportElementInfo()
0962: .createReportElement();
0963: if (columnInfo.getFormat() != null) {
0964: numberFieldReportElement.setFormat(new DecimalFormat(
0965: columnInfo.getFormat()));
0966: }
0967:
0968: textFieldReportElement = numberFieldReportElement;
0969: } else {
0970: textFieldReportElement = ReportElementInfoFactory
0971: .getInstance().getTextFieldReportElementInfo()
0972: .createReportElement();
0973: }
0974:
0975: textFieldReportElement.setFieldName(columnInfo.getColumnName());
0976: Font font = columnInfo.getFont();
0977: if (font != null) {
0978: textFieldReportElement.setFont(font);
0979: }
0980:
0981: Color foregroundColor = columnInfo.getForegroundColor();
0982: if (foregroundColor != null) {
0983: textFieldReportElement.setForeground(foregroundColor);
0984: }
0985:
0986: textFieldReportElement.setBackground(columnInfo
0987: .getBackgroundColor());
0988: textFieldReportElement.setHorizontalAlignment(columnInfo
0989: .getAlignment());
0990:
0991: Rectangle2D bounds = textFieldReportElement.getFont()
0992: .getMaxCharBounds(fontRenderContext);
0993: if (bounds.getHeight() > textFieldReportElement
0994: .getMinimumSize().getHeight()) {
0995: textFieldReportElement.setRectangle(new Rectangle2D.Double(
0996: 0, 0, textFieldReportElement.getMinimumSize()
0997: .getWidth(), bounds.getHeight()));
0998: textFieldReportElement.setMinimumSize(new DoubleDimension(
0999: textFieldReportElement.getMinimumSize().getWidth(),
1000: bounds.getHeight()));
1001: }
1002:
1003: return textFieldReportElement;
1004: }
1005:
1006: protected void externalizeElements(@NotNull
1007: XMLWriter xmlWriter, @NotNull
1008: XMLContext xmlContext) throws IOException {
1009: super .externalizeElements(xmlWriter, xmlContext);
1010:
1011: xmlWriter.writeProperty(PropertyKeys.CONNECTION_TYPE,
1012: connectionType.toString());
1013: String xQueryDataFile = this .xQueryDataFile;
1014: if (xQueryDataFile != null) {
1015: xmlWriter.writeProperty(PropertyKeys.XQUERY_DATA_FILE,
1016: FileRelativator.getRelativePathFromFile(xmlContext,
1017: xQueryDataFile));
1018: }
1019: String xmiDefinitionFile = this .xmiDefinitionFile;
1020: if (xmiDefinitionFile != null) {
1021: xmlWriter.writeProperty(PropertyKeys.XMI_DEFINITION_FILE,
1022: FileRelativator.getRelativePathFromFile(xmlContext,
1023: xmiDefinitionFile));
1024: }
1025: xmlWriter.writeProperty(
1026: PropertyKeys.USE_MONDRIAN_CUBE_DEFINITION, Boolean
1027: .valueOf(useMondrianCubeDefinition).toString());
1028: xmlWriter.writeProperty(
1029: PropertyKeys.MONDRIAN_CUBE_DEFINITION_FILE,
1030: FileRelativator.getRelativePathFromFile(xmlContext,
1031: mondrianCubeDefinitionFile));
1032: xmlWriter.writeProperty(PropertyKeys.LIMIT_PREVIEW_ROWS,
1033: Boolean.valueOf(limitPreviewRows).toString());
1034: xmlWriter.writeProperty(PropertyKeys.MAX_PREVIEW_ROWS, Integer
1035: .valueOf(maxPreviewRows).toString());
1036:
1037: for (Query query : queries) {
1038: xmlWriter.startElement(PropertyKeys.QUERY);
1039: query.externalizeObject(xmlWriter, xmlContext);
1040: xmlWriter.closeElement(PropertyKeys.QUERY);
1041: }
1042:
1043: for (ColumnInfo columnInfo : columnInfos) {
1044: xmlWriter.startElement(PropertyKeys.COLUMN_INFO);
1045: columnInfo.externalizeObject(xmlWriter, xmlContext);
1046: xmlWriter.closeElement(PropertyKeys.COLUMN_INFO);
1047: }
1048:
1049: JNDISource jndiDataSource = selectedJNDIDataSource;
1050: if (jndiDataSource != null) {
1051: xmlWriter
1052: .startElement(PropertyKeys.SELECTED_JNDI_DATA_SOURCE);
1053: jndiDataSource.externalizeObject(xmlWriter, xmlContext);
1054: xmlWriter
1055: .closeElement(PropertyKeys.SELECTED_JNDI_DATA_SOURCE);
1056: }
1057: }
1058:
1059: public void readObject(@NotNull
1060: XmlPullNode node, @NotNull
1061: XMLContext xmlContext) throws Exception {
1062: queries = new ArrayList<Query>();
1063:
1064: super .readObject(node, xmlContext);
1065:
1066: if (queries.isEmpty()) {
1067: queries.add(new Query(
1068: ReportDialogConstants.DEFAULT_DATA_FACTORY, ""));
1069: }
1070: }
1071:
1072: protected void readElement(@NotNull
1073: ExpressionRegistry expressions, @NotNull
1074: XmlPullNode node, @NotNull
1075: XMLContext xmlContext) throws Exception {
1076: super .readElement(expressions, node, xmlContext);
1077:
1078: if (XMLConstants.PROPERTY.equals(node.getRawName())
1079: && PropertyKeys.CONNECTION_TYPE
1080: .equals(node
1081: .getAttributeValueFromRawName(XMLConstants.NAME))) {
1082: connectionType = ConnectionType.valueOf(XMLUtils
1083: .readProperty(PropertyKeys.CONNECTION_TYPE, node));
1084: } else if (XMLConstants.PROPERTY.equals(node.getRawName())
1085: && PropertyKeys.XQUERY_DATA_FILE
1086: .equals(node
1087: .getAttributeValueFromRawName(XMLConstants.NAME))) {
1088: xQueryDataFile = FileRelativator.getAbsoluteFile(
1089: xmlContext, XMLUtils.readProperty(
1090: PropertyKeys.XQUERY_DATA_FILE, node));
1091: } else if (XMLConstants.PROPERTY.equals(node.getRawName())
1092: && PropertyKeys.XMI_DEFINITION_FILE
1093: .equals(node
1094: .getAttributeValueFromRawName(XMLConstants.NAME))) {
1095: xmiDefinitionFile = FileRelativator.getAbsoluteFile(
1096: xmlContext, XMLUtils.readProperty(
1097: PropertyKeys.XMI_DEFINITION_FILE, node));
1098: } else if (XMLConstants.PROPERTY.equals(node.getRawName())
1099: && PropertyKeys.USE_MONDRIAN_CUBE_DEFINITION
1100: .equals(node
1101: .getAttributeValueFromRawName(XMLConstants.NAME))) {
1102: useMondrianCubeDefinition = Boolean.valueOf(
1103: XMLUtils.readProperty(
1104: PropertyKeys.USE_MONDRIAN_CUBE_DEFINITION,
1105: node)).booleanValue();
1106: } else if (XMLConstants.PROPERTY.equals(node.getRawName())
1107: && PropertyKeys.MONDRIAN_CUBE_DEFINITION_FILE
1108: .equals(node
1109: .getAttributeValueFromRawName(XMLConstants.NAME))) {
1110: mondrianCubeDefinitionFile = FileRelativator
1111: .getAbsoluteFile(xmlContext, XMLUtils.readProperty(
1112: PropertyKeys.MONDRIAN_CUBE_DEFINITION_FILE,
1113: node));
1114: } else if (XMLConstants.PROPERTY.equals(node.getRawName())
1115: && PropertyKeys.QUERY_STRING
1116: .equals(node
1117: .getAttributeValueFromRawName(XMLConstants.NAME))) {
1118: Query query = new Query(
1119: ReportDialogConstants.DEFAULT_DATA_FACTORY,
1120: XMLUtils.readProperty(PropertyKeys.QUERY_STRING,
1121: node));
1122: queries.add(query);
1123: } else if (XMLConstants.PROPERTY.equals(node.getRawName())
1124: && PropertyKeys.LIMIT_PREVIEW_ROWS
1125: .equals(node
1126: .getAttributeValueFromRawName(XMLConstants.NAME))) {
1127: limitPreviewRows = Boolean
1128: .parseBoolean(XMLUtils.readProperty(
1129: PropertyKeys.LIMIT_PREVIEW_ROWS, node));
1130: } else if (XMLConstants.PROPERTY.equals(node.getRawName())
1131: && PropertyKeys.MAX_PREVIEW_ROWS
1132: .equals(node
1133: .getAttributeValueFromRawName(XMLConstants.NAME))) {
1134: maxPreviewRows = Integer.parseInt(XMLUtils.readProperty(
1135: PropertyKeys.MAX_PREVIEW_ROWS, node));
1136: } else if (PropertyKeys.QUERY.equals(node.getRawName())) {
1137: Query query = new Query("", "");
1138: query.readObject(node, xmlContext);
1139: queries.add(query);
1140: } else if (PropertyKeys.COLUMN_INFO.equals(node.getRawName())) {
1141: ColumnInfo columnInfo = new ColumnInfo("", "", Object.class);
1142: columnInfo.readObject(node, xmlContext);
1143: columnInfos.add(columnInfo);
1144: } else if (PropertyKeys.SELECTED_JNDI_DATA_SOURCE.equals(node
1145: .getRawName())) {
1146: JNDISource jndiSource = new JNDISource();
1147: jndiSource.readObject(node, xmlContext);
1148: selectedJNDIDataSource = jndiSource;
1149: if (!jndiSources.contains(selectedJNDIDataSource)) {
1150: jndiSources.add(jndiSource);
1151: }
1152: }
1153: }
1154:
1155: public void accept(@Nullable
1156: Object parent, @NotNull
1157: ReportVisitor reportVisitor) throws ReportCreationException {
1158: /* Object newParent = */
1159: reportVisitor.visit(parent, this);
1160: }
1161:
1162: }
|