blob: 55fea3517817e9c2c7c1835ae17b314fcab84244 [file] [log] [blame]
/**
*
* Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
*
*/
package org.eclipse.osbp.utils.vaadin;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.osbp.core.api.persistence.IPersistenceService;
import org.eclipse.osbp.mondrian.api.IMondrianService;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.ui.api.user.IUser;
import org.eclipse.osbp.xtext.datamart.common.olap.DerivedAxis;
import org.eclipse.osbp.xtext.datamart.common.olap.DerivedCell;
import org.eclipse.osbp.xtext.datamart.common.olap.DerivedCellSet;
import org.eclipse.osbp.xtext.datamart.common.olap.DerivedMember;
import org.eclipse.osbp.xtext.datamart.common.olap.DerivedPosition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vaadin.data.Item;
import com.vaadin.server.ClientConnector.DetachListener;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.Table;
import com.vaadin.ui.Table.RowHeaderMode;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import mondrian.olap4j.MondrianOlap4jDriver;
import mondrian.rolap.RolapConnection;
public class MDXDialog extends Window implements DetachListener { // NOSONAR
private static final String MEMBER_TITLE = "member";
/**
*
*/
private static final long serialVersionUID = 3461161019240158996L;
private static final Logger LOGGER = LoggerFactory.getLogger(MDXDialog.class);
private TextArea input;
private Button button;
private Component tableLayout;
private String messageText = "MDX Query";
private String buttonText = "execute";
private String areaText = "Statement";
private String sampleText = "select Non Empty [Measures].[Salary] on columns,Non Empty [Employees].[Employee].Members on rows from Payroll";
private transient IDSLMetadataService dslMetadataService;
private transient RolapConnection connection;
private transient IPersistenceService persistenceService;
private transient IMondrianService mondrianService;
private transient IUser user;
private VerticalLayout subLayout;
private ArrayList<Integer> coordinateSystem = new ArrayList<>();
public MDXDialog(IEclipseContext eclipseContext) {
super();
addDetachListener(this);
dslMetadataService = eclipseContext.get(IDSLMetadataService.class);
persistenceService = eclipseContext.get(IPersistenceService.class);
user = eclipseContext.get(IUser.class);
mondrianService = eclipseContext.get(IMondrianService.class);
setClosable(true);
setModal(false);
VerticalLayout subContent = new VerticalLayout();
subContent.setMargin(true);
setContent(subContent);
setCaption(messageText);
subContent.setSpacing(true);
subLayout = new VerticalLayout();
subContent.addComponent(subLayout);
input = new TextArea(areaText);
input.setRows(6);
input.setWordwrap(true);
input.setSizeFull();
input.setValue(sampleText);
input.setWidth("600px");
input.setHeight("150px");
subLayout.addComponent(input);
button = new Button(buttonText);
button.addClickListener(e -> executeQuery());
subLayout.addComponent(button);
center();
connect();
}
@Override
public void setLocale(Locale locale) {
super.setLocale(locale);
setCaption(dslMetadataService.translate(locale.toLanguageTag(), messageText));
}
private void connect() {
if (connection == null) {
LOGGER.debug("{}", "connect MDX");
try {
// for simplicity we only take the first entity used in a cube definition to establish connection
connection = persistenceService.getMondrianConnection(mondrianService.getPersistenceUnit(),
mondrianService.getPackageName());
} catch (SQLException e) {
LOGGER.error("{}", e);
}
}
}
private void disconnect() {
LOGGER.debug("{}", "disconnect MDX");
if (connection != null) {
connection.close();
connection = null;
}
}
private void executeQuery() {
LOGGER.debug("{}", "execute MDX");
if (tableLayout != null) {
subLayout.removeComponent(tableLayout);
}
RolapConnection rolapConnection = connection;
Connection connection;
// (JCD) : temporarily disabled to avoid errors with mondrian 4
// try {
// connection = new MondrianOlap4jDriver().connect(rolapConnection);
// Statement statement = connection.createStatement();
// ResultSet result = statement.executeQuery(input.getValue());
// } catch (SQLException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
DerivedCellSet cellSet = new DerivedCellSet(persistenceService.sendQuery(this.connection, input.getValue()),
dslMetadataService, user);
coordinateSystem.clear();
for (int axis = 0; axis < cellSet.getAxes().size(); axis++) {
coordinateSystem.add(0);
}
tableLayout = createTabSheet(cellSet, cellSet.getAxes().size());
subLayout.addComponent(tableLayout);
}
private Component createTabSheet(DerivedCellSet cellSet, final Integer axisNo) {
Component component = null;
if (axisNo == 2) {
component = createTable(cellSet);
} else {
Integer axis = axisNo - 1;
TabSheet tabsheet = new TabSheet();
tabsheet.setSizeFull();
DerivedAxis tabAxis = cellSet.getAxes().get(axis);
int tabNo = 0;
for (DerivedPosition column : tabAxis.getPositions()) {
String title = null;
for (DerivedMember member : column.getMembers()) {
if (title == null) {
title = member.getCaption();
} else {
title += " / " + member.getCaption();
}
}
coordinateSystem.set(axis, tabNo);
component = createTabSheet(cellSet, axis);
if (component != null) {
component.setCaption(title);
tabsheet.addComponent(component);
}
tabNo++;
}
component = tabsheet;
}
return component;
}
private Component createTable(DerivedCellSet cellSet) {
List<Integer> coordinate = new ArrayList<>(coordinateSystem);
VerticalLayout container = new VerticalLayout();
Table table = new Table();
table.setImmediate(true);
table.setMultiSelect(false);
table.setSelectable(true);
table.setRowHeaderMode(RowHeaderMode.HIDDEN);
table.setSizeFull();
container.addComponent(table);
if(cellSet.getAxes().size() >= 2 && !cellSet.getAxes().get(1).getPositions().isEmpty()) {
renderTable(cellSet, coordinate, table);
}
return container;
}
private void renderTable(DerivedCellSet cellSet, List<Integer> coordinate, Table table) {
for (int memCnt = 0; memCnt < cellSet.getAxes().get(1).getPositions().iterator().next().getMembers()
.size(); memCnt++) {
String title = MEMBER_TITLE + memCnt;
table.addContainerProperty(title, String.class, null);
}
for (DerivedPosition pos : cellSet.getAxes().get(0).getPositions()) {
String title = null;
for (DerivedMember member : pos.getMembers()) {
if (title == null) {
title = member.getCaption();
} else {
title += " " + member.getCaption();
}
}
if (title != null) {
table.addContainerProperty(title, Double.class, null);
}
}
int rowsNo = 0;
for (DerivedPosition rowsPos : cellSet.getAxes().get(1).getPositions()) {
Object newItem = table.addItem();
int memCnt = 0;
for (DerivedMember member : rowsPos.getMembers()) {
String coltitle = MEMBER_TITLE + memCnt;
Item r = table.getItem(newItem);
r.getItemProperty(coltitle).setValue(member.getUniqueName());
memCnt++;
}
coordinate.set(1, rowsNo);
int columnsNo = 0;
for (DerivedPosition columnsPos : cellSet.getAxes().get(0).getPositions()) {
coordinate.set(0, columnsNo);
Object value = null;
DerivedCell cell = cellSet.getCell(coordinate);
if (cell != null) {
if (cell.getValue() == null) {
value = 0.0;
} else {
value = cell.getValue();
}
}
String title = null;
for (DerivedMember member : columnsPos.getMembers()) {
if (title == null) {
title = member.getCaption();
} else {
title += " " + member.getCaption();
}
}
Item r = table.getItem(newItem);
r.getItemProperty(title).setValue(value);
columnsNo++;
}
rowsNo++;
}
}
@Override
public void detach(DetachEvent event) {
disconnect();
}
}