/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright (c) 2011 Pentaho Corporation.. All rights reserved. * * @author Ezequiel Cuellar */ package org.pentaho.platform.dataaccess.datasource.wizard.sources.multitable; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.pentaho.agilebi.modeler.models.JoinFieldModel; import org.pentaho.agilebi.modeler.models.JoinRelationshipModel; import org.pentaho.agilebi.modeler.models.JoinTableModel; import org.pentaho.agilebi.modeler.models.SchemaModel; import org.pentaho.metadata.model.Domain; import org.pentaho.metadata.model.LogicalColumn; import org.pentaho.metadata.model.LogicalRelationship; import org.pentaho.metadata.model.LogicalTable; import org.pentaho.metadata.model.concept.types.LocalizedString; import org.pentaho.platform.dataaccess.datasource.wizard.service.impl.MultiTableDatasourceDTO; import org.pentaho.ui.xul.XulEventSourceAdapter; import org.pentaho.ui.xul.stereotype.Bindable; import org.pentaho.ui.xul.util.AbstractModelList; public class MultitableGuiModel extends XulEventSourceAdapter { private AbstractModelList<JoinRelationshipModel> joins; private AbstractModelList<JoinTableModel> selectedTables; private AbstractModelList<JoinTableModel> availableTables; private AbstractModelList<JoinTableModel> leftTables; private AbstractModelList<JoinTableModel> rightTables; private JoinTableModel leftJoinTable; private JoinTableModel rightJoinTable; private JoinFieldModel leftKeyField; private JoinFieldModel rightKeyField; private JoinRelationshipModel selectedJoin; private JoinTableModel factTable; private boolean doOlap; public MultitableGuiModel() { this.availableTables = new AbstractModelList<JoinTableModel>(); this.selectedTables = new AbstractModelList<JoinTableModel>(); this.leftTables = new AbstractModelList<JoinTableModel>(); this.rightTables = new AbstractModelList<JoinTableModel>(); this.joins = new AbstractModelList<JoinRelationshipModel>(); this.leftJoinTable = new JoinTableModel(); this.rightJoinTable = new JoinTableModel(); this.selectedJoin = new JoinRelationshipModel(); } @Bindable public AbstractModelList<JoinTableModel> getAvailableTables() { return this.availableTables; } @Bindable public void setAvailableTables(AbstractModelList<JoinTableModel> availableTables) { this.availableTables.setChildren(availableTables); } @Bindable public AbstractModelList<JoinTableModel> getSelectedTables() { return this.selectedTables; } @Bindable public void setSelectedTables(AbstractModelList<JoinTableModel> selectedTables) { this.selectedTables = selectedTables; } @Bindable public JoinTableModel getLeftJoinTable() { return this.leftJoinTable; } @Bindable public void setLeftJoinTable(JoinTableModel leftJoinTable) { this.leftJoinTable = leftJoinTable; } @Bindable public JoinTableModel getRightJoinTable() { return this.rightJoinTable; } @Bindable public void setRightJoinTable(JoinTableModel rightJoinTable) { this.rightJoinTable = rightJoinTable; } @Bindable public JoinFieldModel getLeftKeyField() { return this.leftKeyField; } @Bindable public void setLeftKeyField(JoinFieldModel leftKeyField) { this.leftKeyField = leftKeyField; } @Bindable public JoinFieldModel getRightKeyField() { return this.rightKeyField; } @Bindable public void setRightKeyField(JoinFieldModel rightKeyField) { this.rightKeyField = rightKeyField; } @Bindable public AbstractModelList<JoinRelationshipModel> getJoins() { return this.joins; } @Bindable public void setJoins(AbstractModelList<JoinRelationshipModel> joins) { this.joins = joins; } @Bindable public JoinRelationshipModel getSelectedJoin() { return this.selectedJoin; } @Bindable public void setSelectedJoin(JoinRelationshipModel selectedJoin) { this.selectedJoin = selectedJoin; } @Bindable public JoinTableModel getFactTable() { return factTable; } @Bindable public void setFactTable(JoinTableModel factTable) { this.factTable = factTable; } public void addJoin(JoinRelationshipModel join) { this.joins.add(join); } public void removeSelectedJoin() { this.joins.remove(this.selectedJoin); } public void addSelectedTable(JoinTableModel table) { this.availableTables.remove(table); this.selectedTables.add(table); } public void addSelectedTables(List<JoinTableModel> selected) { this.availableTables.removeAll(selected); this.selectedTables.addAll(selected); } public void removeSelectedTables(List<JoinTableModel> selected) { this.selectedTables.removeAll(selected); this.availableTables.addAll(selected); } public void removeSelectedTable(JoinTableModel table) { this.selectedTables.remove(table); this.availableTables.add(table); } @Bindable public AbstractModelList<JoinTableModel> getLeftTables() { return this.leftTables; } @Bindable public AbstractModelList<JoinTableModel> getRightTables() { return this.rightTables; } @Bindable public boolean isDoOlap() { return this.doOlap; } @Bindable public void setDoOlap(boolean isStar) { this.doOlap = isStar; firePropertyChange("doOlap", !isStar, isStar); } public void computeJoinDefinitionStepTables() { this.leftTables.clear(); this.rightTables.clear(); if(this.doOlap) { this.leftTables.add(this.factTable); for(JoinTableModel table : this.selectedTables) { if(table.equals(this.factTable)) { continue; } else { this.rightTables.add(table); } } } else { this.leftTables.addAll(this.selectedTables); this.rightTables.addAll(this.selectedTables); } } public void processAvailableTables(List<String> tables) { List<JoinTableModel> joinTables = new ArrayList<JoinTableModel>(); for (String table : tables) { JoinTableModel joinTable = new JoinTableModel(); joinTable.setName(table); joinTables.add(joinTable); } Collections.sort(joinTables, new Comparator<JoinTableModel>() { @Override public int compare(JoinTableModel joinTableModel, JoinTableModel joinTableModel1) { return joinTableModel.getName().compareTo(joinTableModel1.getName()); } }); setAvailableTables(new AbstractModelList<JoinTableModel>(joinTables)); } @Deprecated public List<LogicalRelationship> generateLogicalRelationships(List<JoinRelationshipModel> joins) { String locale = LocalizedString.DEFAULT_LOCALE; List<LogicalRelationship> logicalRelationships = new ArrayList<LogicalRelationship>(); for (JoinRelationshipModel join : joins) { LogicalTable fromTable = new LogicalTable(); fromTable.setName(new LocalizedString(locale, join.getLeftKeyFieldModel().getParentTable().getName())); LogicalTable toTable = new LogicalTable(); toTable.setName(new LocalizedString(locale, join.getRightKeyFieldModel().getParentTable().getName())); LogicalColumn fromColumn = new LogicalColumn(); fromColumn.setName(new LocalizedString(locale, join.getLeftKeyFieldModel().getName())); LogicalColumn toColumn = new LogicalColumn(); toColumn.setName(new LocalizedString(locale, join.getRightKeyFieldModel().getName())); LogicalRelationship logicalRelationship = new LogicalRelationship(); logicalRelationship.setFromTable(fromTable); logicalRelationship.setToTable(toTable); logicalRelationship.setFromColumn(fromColumn); logicalRelationship.setToColumn(toColumn); logicalRelationships.add(logicalRelationship); } return logicalRelationships; } public MultiTableDatasourceDTO createMultiTableDatasourceDTO(String dsName) { MultiTableDatasourceDTO dto = new MultiTableDatasourceDTO(); dto.setDoOlap(this.doOlap); dto.setDatasourceName(dsName); List<String> selectedTables = new ArrayList<String>(); for (JoinTableModel tbl : this.selectedTables) { selectedTables.add(tbl.getName()); } dto.setSelectedTables(selectedTables); SchemaModel schema = new SchemaModel(); schema.setJoins(this.getJoins()); schema.setFactTable(this.factTable); dto.setSchemaModel(schema); return dto; } public void populateJoinGuiModel(Domain domain, MultiTableDatasourceDTO dto) { // existing joinTableModels will not have fields. We can add these from // the domain. addFieldsToTables(domain, this.availableTables); // Populate "selectedTables" from availableTables using // logicalRelationships. AbstractModelList<JoinTableModel> selectedTablesList = new AbstractModelList<JoinTableModel>(); for (String selectedTable : dto.getSelectedTables()) { this.selectTable(selectedTable, selectedTablesList); } this.selectedTables.addAll(selectedTablesList); this.joins.addAll(dto.getSchemaModel().getJoins()); this.setDoOlap(dto.isDoOlap()); if(dto.isDoOlap()) { this.setFactTable(dto.getSchemaModel().getFactTable()); } } private void addFieldsToTables(Domain domain, AbstractModelList<JoinTableModel> availableTables) { String locale = LocalizedString.DEFAULT_LOCALE; for (JoinTableModel table : availableTables) { for (LogicalTable tbl : domain.getLogicalModels().get(0).getLogicalTables()) { if(tbl.getPhysicalTable().getProperty("target_table").equals(table.getName())){ for (LogicalColumn col : tbl.getLogicalColumns()) { JoinFieldModel field = new JoinFieldModel(); field.setName(col.getName(locale)); field.setParentTable(table); table.getFields().add(field); } continue; } } } } private void selectTable(String selectedTable, AbstractModelList<JoinTableModel> selectedTablesList) { for (JoinTableModel table : this.availableTables) { if (table.getName().equals(selectedTable)) { if (!selectedTablesList.contains(table)) { selectedTablesList.add(table); } } } } public void reset() { this.availableTables.clear(); this.selectedTables.clear(); this.joins.clear(); this.leftJoinTable.reset(); this.rightJoinTable.reset(); } }