package org.pentaho.reporting.engine.classic.core.modules.misc.connections; import org.pentaho.database.model.IDatabaseConnection; import org.pentaho.reporting.engine.classic.core.ClassicEngineBoot; import org.pentaho.reporting.libraries.base.util.ArgumentNullException; import org.pentaho.reporting.libraries.base.util.ObjectUtilities; import org.pentaho.reporting.libraries.base.util.StringUtils; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.UUID; /** * Designtime support class. */ public class EditDataSourceMgmtService implements DataSourceMgmtService { private DataSourceMgmtService parent; private Set<String> deletedMembersById; private HashMap<String, SerializedConnection> editedMembers; public EditDataSourceMgmtService() { this( ClassicEngineBoot.getInstance().getObjectFactory().get( DataSourceMgmtService.class ) ); } public EditDataSourceMgmtService( final DataSourceMgmtService parent ) { ArgumentNullException.validate( "parent", parent ); this.parent = parent; deletedMembersById = new HashSet<String>(); editedMembers = new HashMap<String, SerializedConnection>(); } public String createDatasource( final IDatabaseConnection databaseConnection ) throws DuplicateDatasourceException, DatasourceMgmtServiceException { final String name = databaseConnection.getName(); if ( StringUtils.isEmpty( name ) ) { throw new IllegalArgumentException(); } try { if ( getDatasourceByName( name ) != null ) { throw new DuplicateDatasourceException(); } } catch ( NonExistingDatasourceException nde ) { // expected exception as a result of the getDatasourceByName call. } final String id = UUID.randomUUID().toString(); databaseConnection.setId( id ); editedMembers.put( id, new SerializedConnection( databaseConnection ) ); return id; } public void deleteDatasourceById( final String id ) throws NonExistingDatasourceException, DatasourceMgmtServiceException { if ( StringUtils.isEmpty( id ) ) { throw new IllegalArgumentException(); } if ( parent.getDatasourceIds().contains( id ) ) { deletedMembersById.add( id ); } else if ( !editedMembers.containsKey( id ) ) { throw new NonExistingDatasourceException(); } editedMembers.remove( id ); } public IDatabaseConnection getDatasourceByName( final String name ) throws DatasourceMgmtServiceException { final IDatabaseConnection dataSource = parent.getDatasourceByName( name ); if ( deletedMembersById.contains( dataSource.getId() ) ) { throw new NonExistingDatasourceException(); } return dataSource; } public IDatabaseConnection getDatasourceById( final String id ) throws DatasourceMgmtServiceException { if ( deletedMembersById.contains( id ) ) { throw new NonExistingDatasourceException(); } return parent.getDatasourceById( id ); } public List<IDatabaseConnection> getDatasources() throws DatasourceMgmtServiceException { final ArrayList<IDatabaseConnection> connection = new ArrayList<IDatabaseConnection>( parent.getDatasources() ); final Iterator<IDatabaseConnection> it = connection.iterator(); while ( it.hasNext() ) { final IDatabaseConnection databaseConnection = it.next(); if ( deletedMembersById.contains( databaseConnection.getId() ) ) { it.remove(); } } return connection; } public List<String> getDatasourceIds() throws DatasourceMgmtServiceException { final List<IDatabaseConnection> datasources = getDatasources(); final List<String> list = new ArrayList<String>(); for ( int i = 0; i < datasources.size(); i++ ) { final IDatabaseConnection connection = datasources.get( i ); list.add( connection.getId() ); } return list; } public String updateDatasourceById( final String id, final IDatabaseConnection databaseConnection ) throws NonExistingDatasourceException, DatasourceMgmtServiceException { if ( StringUtils.isEmpty( id ) ) { throw new IllegalArgumentException(); } if ( ObjectUtilities.equal( id, databaseConnection.getId() ) == false ) { // the Pentaho-datasources API is ill defined and allows bad behaviour. throw new IllegalArgumentException(); } if ( deletedMembersById.contains( id ) ) { throw new NonExistingDatasourceException(); } editedMembers.put( id, new SerializedConnection( databaseConnection ) ); return id; } public void commit() { for ( final String id : deletedMembersById ) { parent.deleteDatasourceById( id ); } final Set<String> datasourceIds = new HashSet<String>( parent.getDatasourceIds() ); for ( final SerializedConnection c : editedMembers.values() ) { final IDatabaseConnection connection = c.getConnection(); if ( datasourceIds.contains( connection.getId() ) ) { parent.updateDatasourceById( connection.getId(), connection ); } else { parent.createDatasource( connection ); } } deletedMembersById.clear(); editedMembers.clear(); } }