Advertisement
Guest User

Untitled

a guest
Aug 13th, 2013
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import java.io.IOException;
  2. import java.sql.CallableStatement;
  3. import java.sql.Connection;
  4. import java.sql.PreparedStatement;
  5. import java.sql.ResultSet;
  6. import java.sql.SQLException;
  7.  
  8. import javax.annotation.PostConstruct;
  9. import javax.sql.DataSource;
  10.  
  11. import org.apache.commons.dbutils.ResultSetHandler;
  12. import org.springframework.beans.factory.BeanInitializationException;
  13. import org.springframework.jdbc.datasource.AbstractDataSource;
  14. import org.springframework.util.Assert;
  15. import org.springframework.web.context.request.RequestAttributes;
  16. import org.springframework.web.context.request.RequestContextHolder;
  17.  
  18. import com.google.common.collect.HashBasedTable;
  19. import com.google.common.collect.Table;
  20. import com.ibm.as400.access.AS400;
  21. import com.ibm.as400.access.AS400JDBCDataSource;
  22. import com.ibm.as400.access.AS400SecurityException;
  23. import com.ibm.as400.access.ErrorCompletingRequestException;
  24. import com.ibm.as400.access.ObjectDoesNotExistException;
  25. import com.ibm.as400.access.User;
  26.  
  27. /**
  28.  *
  29.  * @author bsanders
  30.  *
  31.  */
  32. public class AS400UserEnvironmentDataSource extends AbstractDataSource {
  33.  
  34.     private AS400 system;
  35.     private User anonymousUser;
  36.    
  37.     private String
  38.         userAttribute = "user",
  39.         environmentAttribute = "environment";
  40.  
  41.     private boolean dataSourcePerUser;
  42.    
  43.     private Table<String, User, DataSource> targetDataSources;
  44.    
  45.     public AS400UserEnvironmentDataSource() {}
  46.  
  47.     /**
  48.      * Called after dependencies have been injected to perform initialization.
  49.      * If an object of this class is instantiated outside of an IOC container, then this method must be called manually.
  50.      */
  51.     @PostConstruct
  52.     public void afterPropertiesSet() {
  53.         try {
  54.             logger.info("Initializing datasource...");
  55.            
  56.             Assert.notNull(system, "system property must not be null");
  57.             anonymousUser = new User(system, system.getUserId());
  58.            
  59.             Connection connection = new AS400JDBCDataSource(system).getConnection();
  60.             PreparedStatement stmt = connection.prepareStatement("SELECT LLLLID FROM KAUTL400DT.KALLM");            
  61.             targetDataSources = new UserEnvironmentDataSourceTableHandler("LLLLID").handle(stmt.executeQuery());
  62.         }
  63.         catch (SQLException | AS400SecurityException | ErrorCompletingRequestException | InterruptedException | IOException | ObjectDoesNotExistException e) {
  64.             throw new BeanInitializationException("Unable to initialize datasource", e);
  65.         }
  66.     }
  67.    
  68.     /**
  69.      * Sets the {@link AS400} session to use when initializing the datasource
  70.      * @param system An {@link AS400} session with the proper authorization to access the list of available environments
  71.      */
  72.     public void setSystem(AS400 system) {
  73.         this.system = system;
  74.     }
  75.  
  76.     /**
  77.      * Used by {@link #getTargetDataSource()} to determine the proper {@link DataSource} to return.
  78.      * Default value is "user".
  79.      *
  80.      * @return The session attribute in which this datasource can find the {@link User}
  81.      */
  82.     public String getUserAttribute() {
  83.         return userAttribute;
  84.     }
  85.    
  86.     /**
  87.      *
  88.      * @param userAttribute The session attribute in which {@link #getTargetDataSource()} can expect to find the associated {@link #getUser() user}
  89.      */
  90.     public void setUserAttribute(String userAttribute) {
  91.         this.userAttribute = userAttribute;
  92.     }
  93.    
  94.     /**
  95.      * Used by {@link #getTargetDataSource()} to determine the proper {@link DataSource} to return
  96.      *
  97.      * @return The session attribute in which this datasource can find the {@link #getEnvironment() environment}
  98.      */
  99.     public String getEnvironmentAttribute() {
  100.         return environmentAttribute;
  101.     }
  102.  
  103.     /**
  104.      *
  105.      * @param environmentAttribute
  106.      */
  107.     public void setEnvironmentAttribute(String environmentAttribute) {
  108.         this.environmentAttribute = environmentAttribute;
  109.     }
  110.  
  111.     /**
  112.      *
  113.      * @return
  114.      */
  115.     public boolean isDataSourcePerUser() {
  116.         return dataSourcePerUser;
  117.     }
  118.    
  119.     /**
  120.      *
  121.      * @param dataSourcePerUser
  122.      */
  123.     public void setDataSourcePerUser(boolean dataSourcePerUser) {
  124.         this.dataSourcePerUser = dataSourcePerUser;
  125.     }
  126.    
  127.     /**
  128.      *
  129.      * @return A {@link DataSource}
  130.      * @throws IllegalArgumentException
  131.      */
  132.     private DataSource getTargetDataSource() {
  133.         String environment = getEnvironment();
  134.         User user = getUser();
  135.        
  136.         if (targetDataSources.get(environment, user) == null) {
  137.             AS400JDBCDataSource datasource = new AS400JDBCDataSource(user.getSystem());
  138.             datasource.setNaming("system");
  139.            
  140.             targetDataSources.put(environment, user, datasource);
  141.         }
  142.        
  143.         return targetDataSources.get(environment, user);
  144.     }
  145.  
  146.     /**
  147.      * Convenient method to retrieve values from the session map
  148.      *  
  149.      * @param name The key of the value you want to retrieve
  150.      * @return The value, if any
  151.      */
  152.     private Object getSessionAttribute(String name) {
  153.         return RequestContextHolder.currentRequestAttributes().getAttribute(name, RequestAttributes.SCOPE_SESSION);
  154.     }
  155.  
  156.     /**
  157.      * Called by {@link #getTargetDataSource()} to determine which {@link User} will act as a key in the datasource table.
  158.      *
  159.      * @return The value of the session attribute indicated by {@link #getUserAttribute()} if {@link #isDataSourcePerUser()} is true.
  160.      * Otherwise, returns the user associated with {@link #system}.
  161.      */
  162.     private User getUser() {
  163.         User user = isDataSourcePerUser() ? (User) getSessionAttribute(getUserAttribute()) : anonymousUser;
  164.         Assert.notNull(user, "No user found in session attribute \"" + getUserAttribute() + "\"");
  165.        
  166.         return user;
  167.     }
  168.    
  169.     /**
  170.      * returns the current {@link String environment} from the session using the specified {@link #getEnvironmentAttribute() environmentAttribute}
  171.      * @return The name of the environment
  172.      */
  173.     private String getEnvironment() {
  174.         String environment = (String) getSessionAttribute(getEnvironmentAttribute());
  175.         Assert.notNull(environment, "Unable to determine environment because session attribute \"" + getEnvironmentAttribute() + "\" is null");
  176.         Assert.isTrue(targetDataSources.containsRow(environment), "Environment doesn't exist: " + environment);
  177.        
  178.         return environment;
  179.     }
  180.    
  181.     @Override
  182.     public Connection getConnection() throws SQLException {
  183.         Connection connection = getTargetDataSource().getConnection();
  184.        
  185.         String cmd = String.format("KALLM LLID(%s)", getEnvironment().trim());
  186.        
  187.         //Tried using placeholders, but kept getting "Descriptor index not valid"
  188.         CallableStatement stmt = connection.prepareCall(String.format("CALL QCMDEXC ('%s', %d)", cmd, cmd.length()));
  189.         stmt.execute();
  190.         stmt.close();
  191.        
  192.         return connection;
  193.     }
  194.  
  195.     @Override
  196.     public Connection getConnection(String username, String password) throws SQLException {
  197.         return getTargetDataSource().getConnection(username, password);
  198.     }
  199.    
  200.     private static class UserEnvironmentDataSourceTableHandler implements ResultSetHandler<Table<String, User, DataSource>> {
  201.  
  202.         private String rowKeyColumnName;
  203.        
  204.         public UserEnvironmentDataSourceTableHandler(String rowKeyColumnName) {
  205.             this.rowKeyColumnName = rowKeyColumnName;
  206.         }
  207.        
  208.         @Override
  209.         public Table<String, User, DataSource> handle(ResultSet rs) throws SQLException {
  210.             HashBasedTable<String, User, DataSource> result = HashBasedTable.create();
  211.  
  212.             User defaultUser = new User();
  213.             AS400JDBCDataSource defaultDataSource = new AS400JDBCDataSource();
  214.  
  215.             while (rs.next()) {
  216.                 result.put(rs.getString(rowKeyColumnName), defaultUser, defaultDataSource);
  217.             }
  218.            
  219.             return result;
  220.         }
  221.        
  222.     }
  223. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement