/** * i-net software provides programming examples for illustration only, without warranty * either expressed or implied, including, but not limited to, the implied warranties * of merchantability and/or fitness for a particular purpose. This programming example * assumes that you are familiar with the programming language being demonstrated and * the tools used to create and debug procedures. i-net software support professionals * can help explain the functionality of a particular procedure, but they will not modify * these examples to provide added functionality or construct procedures to meet your * specific needs. * * Copyright © 1999-2026 i-net software GmbH, Berlin, Germany. **/ package com.inet.taskplanner.databaseaction; import static com.inet.taskplanner.databaseaction.TaskPlannerDatabaseActionServerPlugin.MSG; import java.net.URL; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import javax.annotation.Nonnull; import javax.annotation.Nullable; import com.inet.config.structure.model.LocalizedKey; import com.inet.id.GUID; import com.inet.plugin.ServerPluginManager; import com.inet.taskplanner.server.api.action.ResultActionDefinition; import com.inet.taskplanner.server.api.action.ResultActionFactory; import com.inet.taskplanner.server.api.action.ResultActionInfo; import com.inet.taskplanner.server.api.common.SummaryEntry; import com.inet.taskplanner.server.api.common.SummaryInfo; import com.inet.taskplanner.server.api.error.ValidationException; import com.inet.taskplanner.server.api.field.Field; import com.inet.taskplanner.server.api.field.SelectField; import com.inet.taskplanner.server.api.field.TextField; import com.inet.taskplanner.server.api.result.ResultFlavor; import com.inet.taskplanner.server.api.series.db.DataSourceProvider; /** * A result action factory defines how the action is presented to the user and may include validation of user-configurable properties. *
* This factory produces actions that allow saving files into the configured database, using the configured Data Source. */ public class DataSourceDatabaseResultActionFactory extends ResultActionFactory { /** * Key of the data source property. */ public static final String DATASOURCE = "datasource"; /** * Key of the table property. */ public static final String TABLE = "table"; /** * Key of the file column property. */ public static final String FILE_COLUMN = "filecolumn"; /** * Key of the optional identifier column property. */ public static final String IDENTIFIER_COLUMN = "identifiercolumn"; /** * Key of the value property for identifier column. Type of value may be long or string. */ public static final String IDENTIFIER_VALUE = "identifiervalue"; /** * Creates instance of the factory. */ public DataSourceDatabaseResultActionFactory() { super( "action.database.datasource" ); } /** * {@inheritDoc} */ @Override public boolean isAvailable() { // Action is available only if provider of connections to data sources is available return getOptionalDataSourceProvider() != null; } /** Returns data source provider or null, if it is not available. * @return data source provider or null, if it is not available. */ private DataSourceProvider getOptionalDataSourceProvider() { return ServerPluginManager.getInstance().getOptionalInstance( DataSourceProvider.class ); } /** * {@inheritDoc} */ @Override public List getSupportedFlavors( ResultActionDefinition definition ) { // Actions produced by this factory are interested in file results return Arrays.asList( ResultFlavor.FILE ); } /** * {@inheritDoc} */ @Override public ResultActionInfo getInformation( @Nullable GUID taskID ) { String name = MSG.getMsg( "taskplanner.databaseaction.name.datasource" ); // A meaningful name String description = MSG.getMsg( "taskplanner.databaseaction.description.datasource" ); // A short description URL icon = getClass().getResource( "/com/inet/taskplanner/databaseaction/taskplanner_databaseaction_32.png" ); // white and transparent icon in 32x32 pixels String helpkey = null; // The result action does not have its own help page List fields = new ArrayList(); // Fields displayed for configuration. Use null if no configuration is required. // Creates list with available data sources List dataSourceNames = getOptionalDataSourceProvider().getDataSourceNames(); if( !dataSourceNames.isEmpty() ) { Collections.sort( dataSourceNames ); ArrayList values = new ArrayList<>(); for( String dataSourceName : dataSourceNames ) { values.add( new LocalizedKey( dataSourceName, dataSourceName ) ); } SelectField selectField = new SelectField( DATASOURCE, MSG.getMsg( "taskplanner.databaseaction.datasource" ), values ); selectField.setValue( values.get( 0 ).getKey() ); fields.add( selectField ); } fields.add( new TextField( TABLE, MSG.getMsg( "taskplanner.databaseaction.table" ) ) ); fields.add( new TextField( FILE_COLUMN, MSG.getMsg( "taskplanner.databaseaction.filecolumn" ) ) ); TextField identifierColumnField = new TextField( IDENTIFIER_COLUMN, MSG.getMsg( "taskplanner.databaseaction.identifiercolumn" ) ); identifierColumnField.setPlaceholder( MSG.getMsg( "taskplanner.databaseaction.placeholder.optional" ) ); fields.add( identifierColumnField ); TextField identifierValueField = new TextField( IDENTIFIER_VALUE, MSG.getMsg( "taskplanner.databaseaction.identifiervalue" ) ); identifierValueField.setPlaceholder( MSG.getMsg( "taskplanner.databaseaction.placeholder.optional" ) ); fields.add( identifierValueField ); return new ResultActionInfo( getExtensionName(), name, description, icon, helpkey, fields ); } /** * {@inheritDoc} */ @Override protected void validate( @Nonnull ResultActionDefinition definition, @Nullable GUID taskID ) throws ValidationException { String datasource = definition.getProperty( DATASOURCE ); String table = definition.getProperty( TABLE ); String fileColumn = definition.getProperty( FILE_COLUMN ); // Checks whether data source, table and column names are provided if( datasource == null || datasource.trim().isEmpty() ) { throw new ValidationException( MSG.getMsg( "taskplanner.databaseaction.datasource.empty" ) ); } if( table == null || table.trim().isEmpty() ) { throw new ValidationException( MSG.getMsg( "taskplanner.databaseaction.table.empty" ) ); } if( fileColumn == null || fileColumn.trim().isEmpty() ) { throw new ValidationException( MSG.getMsg( "taskplanner.databaseaction.filecolumn.empty" ) ); } // Checks whether connection to the database is possible and whether configured table exists String sql = "SELECT COUNT(*) FROM " + table; try (Connection con = getOptionalDataSourceProvider().getConnection( datasource ); Statement stm = con.createStatement(); ResultSet rs = stm.executeQuery( sql )) { if( rs.next() ) { rs.getInt( 1 ); } } catch( Exception ex ) { throw new ValidationException( ex.getMessage() ); } } /** * {@inheritDoc} */ @Override protected DataSourceDatabaseResultAction createInstanceFrom( @Nonnull ResultActionDefinition definition ) { String datasource = definition.getProperty( DATASOURCE ); String table = definition.getProperty( TABLE ); String fileColumn = definition.getProperty( FILE_COLUMN ); String identifierColumn = definition.getProperty( IDENTIFIER_COLUMN ); String identifierValue = definition.getProperty( IDENTIFIER_VALUE ); if( identifierColumn == null || identifierColumn.trim().isEmpty() ) { return new DataSourceDatabaseResultAction( getOptionalDataSourceProvider(), datasource, table, fileColumn ); } return new DataSourceDatabaseResultAction( getOptionalDataSourceProvider(), datasource, table, fileColumn, identifierColumn, identifierValue ); } /** * {@inheritDoc} */ @Override public SummaryInfo getSummary( @Nonnull ResultActionDefinition definition ) { List result = new ArrayList<>(); result.add( new SummaryEntry( MSG.getMsg( "taskplanner.databaseaction.datasource" ), definition.getProperty( DATASOURCE ) ) ); result.add( new SummaryEntry( MSG.getMsg( "taskplanner.databaseaction.table" ), definition.getProperty( TABLE ) ) ); result.add( new SummaryEntry( MSG.getMsg( "taskplanner.databaseaction.filecolumn" ), definition.getProperty( FILE_COLUMN ) ) ); String identifierColumn = definition.getProperty( IDENTIFIER_COLUMN ); if( identifierColumn != null && !identifierColumn.trim().isEmpty() ) { result.add( new SummaryEntry( MSG.getMsg( "taskplanner.databaseaction.identifiercolumn" ), identifierColumn ) ); } String identifierValue = definition.getProperty( IDENTIFIER_VALUE ); if( identifierValue != null && !identifierValue.trim().isEmpty() ) { result.add( new SummaryEntry( MSG.getMsg( "taskplanner.databaseaction.identifiervalue" ), identifierValue ) ); } return new SummaryInfo( result ); } }