/*! * 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) 2002-2013 Pentaho Corporation.. All rights reserved. */ package org.pentaho.platform.dataaccess.datasource.wizard.models; import org.pentaho.database.model.IDatabaseConnection; import org.pentaho.metadata.model.Category; import org.pentaho.metadata.model.Domain; import org.pentaho.metadata.model.LogicalColumn; import org.pentaho.metadata.model.LogicalModel; import org.pentaho.platform.dataaccess.datasource.DatasourceType; import org.pentaho.ui.xul.XulEventSourceAdapter; import org.pentaho.ui.xul.binding.BindingException; import org.pentaho.ui.xul.stereotype.Bindable; //TODO: this class is a mixture of CSV and Relational model code... break it up! @Deprecated public class DatasourceModel extends XulEventSourceAdapter implements IRelationalModelValidationListener, IModelInfoValidationListener { private boolean validated; private DatasourceType datasourceType = DatasourceType.NONE; private transient GuiStateModel guiStateModel; private ModelInfo modelInfo; private Domain domain; private String datasourceName; private IDatabaseConnection selectedRelationalConnection; private String query; private boolean editMode; public DatasourceModel() { guiStateModel = new GuiStateModel(); guiStateModel.addRelationalModelValidationListener( this ); CsvFileInfo fileInfo = new CsvFileInfo(); modelInfo = new ModelInfo(); modelInfo.setFileInfo( fileInfo ); modelInfo.addModelInfoValidationListener( this ); } @Bindable public GuiStateModel getGuiStateModel() { return guiStateModel; } @Bindable public void setGuiStateModel( GuiStateModel guiStateModel ) { this.guiStateModel = guiStateModel; } @Bindable public String getDatasourceName() { return datasourceName; } @Bindable public void setDatasourceName( String datasourceName ) { String previousVal = this.datasourceName; this.datasourceName = datasourceName; // if we're editing a generated or already defined domain, // we need to keep the datasource name in sync if ( domain != null ) { domain.setId( datasourceName ); LogicalModel model = domain.getLogicalModels().get( 0 ); String localeCode = domain.getLocales().get( 0 ).getCode(); model.getName().setString( localeCode, datasourceName ); } this.getModelInfo().setStageTableName( generateTableName() ); this.firePropertyChange( "datasourceName", previousVal, datasourceName ); //$NON-NLS-1$ validate(); } @Bindable public IDatabaseConnection getSelectedRelationalConnection() { return selectedRelationalConnection; } @Bindable public void setSelectedRelationalConnection( IDatabaseConnection value ) { try { IDatabaseConnection previousValue = this.selectedRelationalConnection; this.selectedRelationalConnection = value; if ( value != null ) { this.firePropertyChange( "selectedRelationalConnection", previousValue, value ); validate(); } } catch ( BindingException e ) { // ignore since any binding issues with datasource parameters will be more obviously caught elsewhere } } @Bindable public String getQuery() { return query; } @Bindable public void setQuery( String value ) { String previousVal = this.query; this.query = value; this.firePropertyChange( "query", previousVal, value ); //$NON-NLS-1$ validate(); } public Domain getDomain() { return domain; } public void setDomain( Domain domain ) { this.domain = domain; if ( domain != null ) { guiStateModel.setLogicalModels( domain.getLogicalModels() ); guiStateModel.setLocaleCode( domain.getLocales().get( 0 ).getCode() ); } else { guiStateModel.setLogicalModels( null ); guiStateModel.setLocaleCode( null ); } } @Bindable public ModelInfo getModelInfo() { return modelInfo; } @Bindable public void setModelInfo( ModelInfo modelInfo ) { // to avoid un-wiring bindings, don't just blow away the modelinfo object this.modelInfo.getFileInfo().setSavedEncoding( modelInfo.getFileInfo().getEncoding() ); this.modelInfo.setColumns( modelInfo.getColumns() ); this.modelInfo.setData( modelInfo.getData() ); this.modelInfo.setStageTableName( modelInfo.getStageTableName() ); this.modelInfo.getFileInfo().setDelimiter( modelInfo.getFileInfo().getDelimiter() ); this.modelInfo.getFileInfo().setContents( modelInfo.getFileInfo().getContents() ); this.modelInfo.getFileInfo().setCurrencySymbol( modelInfo.getFileInfo().getCurrencySymbol() ); this.modelInfo.getFileInfo().setEnclosure( modelInfo.getFileInfo().getEnclosure() ); this.modelInfo.getFileInfo().setEncoding( modelInfo.getFileInfo().getEncoding() ); this.modelInfo.getFileInfo().setFilename( modelInfo.getFileInfo().getFilename() ); this.modelInfo.getFileInfo().setTmpFilename( modelInfo.getFileInfo().getTmpFilename() ); this.modelInfo.getFileInfo().setGroupSymbol( modelInfo.getFileInfo().getGroupSymbol() ); this.modelInfo.getFileInfo().setHeaderRows( modelInfo.getFileInfo().getHeaderRows() ); this.modelInfo.getFileInfo().setIfNull( modelInfo.getFileInfo().getIfNull() ); this.modelInfo.getFileInfo().setNullStr( modelInfo.getFileInfo().getNullStr() ); this.modelInfo.getFileInfo().setProject( modelInfo.getFileInfo().getProject() ); this.modelInfo.getFileInfo().setFriendlyFilename( modelInfo.getFileInfo().getFriendlyFilename() ); modelInfo.validate(); validate(); } @Bindable public boolean isValidated() { return validated; } @Bindable private void setValidated( boolean validated ) { boolean prevVal = this.validated; this.validated = validated; this.firePropertyChange( "validated", prevVal, validated ); //$NON-NLS-1$ } @Bindable public DatasourceType getDatasourceType() { return this.datasourceType; } @Bindable public void setDatasourceType( DatasourceType datasourceType ) { DatasourceType previousVal = this.datasourceType; this.datasourceType = datasourceType; this.firePropertyChange( "datasourceType", previousVal, datasourceType ); //$NON-NLS-1$ validate(); } public void validate() { boolean value = false; if ( datasourceName != null && datasourceName.length() > 0 ) { if ( DatasourceType.SQL == getDatasourceType() && getSelectedRelationalConnection() != null && query != null && query.length() > 0 ) { guiStateModel.validateRelational(); value = guiStateModel.isRelationalValidated(); } else if ( DatasourceType.CSV == getDatasourceType() ) { guiStateModel.invalidateRelational(); value = modelInfo.isValidated(); } } else { guiStateModel.invalidateRelational(); } setValidated( value ); } /* * Clears out the model */ public void clearModel() { // clear the models before switching the datasource type, otherwise // an error is presented to the user. setQuery( "" ); setDatasourceName( "" ); guiStateModel.clearModel(); // BISERVER-3664: Temporary solution for IE ListBoxs not accepting -1 selectedIndex. // Explicitly selecting the first connection object makes all browsers behave the same. IDatabaseConnection firstConnection = guiStateModel.getConnections().size() > 0 ? guiStateModel.getConnections().get( 0 ) : null; setSelectedRelationalConnection( firstConnection ); modelInfo.clearModel(); guiStateModel.setDataStagingComplete( false ); setDatasourceType( DatasourceType.NONE ); validate(); } // @Bindable // public IDatasource getDatasource() { // IDatasource datasource = new Datasource(); // if(DatasourceType.SQL == getDatasourceType()) { // datasource.setBusinessData(getRelationalModel().getBusinessData()); // datasource.setConnections(getRelationalModel().getConnections()); // datasource.setQuery(getRelationalModel().getQuery()); // datasource.setSelectedConnection(getRelationalModel().getSelectedConnection()); // } else { // datasource.setBusinessData(null); // datasource.setSelectedFile(getModelInfo().getFileInfo().getFilename()); // datasource.setHeadersPresent(getModelInfo().getFileInfo().getHeaderRows() > 0); // // } // return datasource; // } public void onRelationalModelInValid() { if ( DatasourceType.SQL == getDatasourceType() ) { setValidated( false ); } } public void onRelationalModelValid() { if ( DatasourceType.SQL == getDatasourceType() ) { setValidated( true ); } } /** * This is a utility method that looks into an old domain for the same column ids, and then copies over the old * metadata into the new. * * @param oldDomain * @param newDomain */ public void copyOverMetadata( Domain oldDomain, Domain newDomain ) { Category category = newDomain.getLogicalModels().get( 0 ).getCategories().get( 0 ); LogicalModel oldModel = oldDomain.getLogicalModels().get( 0 ); for ( LogicalColumn column : category.getLogicalColumns() ) { LogicalColumn oldColumn = oldModel.findLogicalColumn( column.getId() ); if ( oldColumn != null ) { column.setDataType( oldColumn.getDataType() ); column.setName( oldColumn.getName() ); column.setAggregationList( oldColumn.getAggregationList() ); column.setAggregationType( oldColumn.getAggregationType() ); } } } public void onModelInfoInvalid() { if ( DatasourceType.CSV == getDatasourceType() ) { setValidated( false ); } } public void onModelInfoValid() { if ( DatasourceType.CSV == getDatasourceType() ) { setValidated( true ); } } /** * Strips all non-alphanumeric characters from the datasourceName, replaces spaces with underscores, and finally * lowercases the string for return making it valid for use as a table name * * @return */ public String generateTableName() { if ( datasourceName == null ) { throw new IllegalStateException( "DatasourceName must not be null, cannot generate a valid table name" ); //$NON-NLS-1$ } return datasourceName.trim().replace( " ", "_" ) //$NON-NLS-1$ //$NON-NLS-2$ .replaceAll( "[^A-Za-z0-9_-]", "" ) //$NON-NLS-1$ //$NON-NLS-2$ .toLowerCase(); // change to lower to handle case sensitivity of quoted table names in postgresql (which // defaults all tables to lowercase)... BISERVER-5231 } public void onCsvInValid() { } public void onCsvValid() { } public boolean isEditing() { return editMode; } public void setEditing( boolean editing ) { this.editMode = editing; } }