View Javadoc

1   package net.sf.sapjcosupport.jdbc;
2   
3   import com.sap.mw.jco.IRepository;
4   import com.sap.mw.jco.JCO;
5   import org.apache.commons.lang.Validate;
6   import org.apache.log4j.Logger;
7   
8   import java.io.PrintWriter;
9   import java.sql.Connection;
10  import java.sql.SQLException;
11  
12  /**
13   * Created by IntelliJ IDEA.
14   * User: NDE1677
15   * Date: Jul 5, 2006
16   * Time: 12:50:26 PM
17   * To change this template use File | Settings | File Templates.
18   */
19  public class SapDataSource implements javax.sql.DataSource {
20      /**
21       * Login time out in seconds.
22       * Defaults to one minute.
23       */
24      private int loginTimeout = 60;
25      private PrintWriter logWriter = null;
26  
27      private static final Logger logger = Logger.getLogger(SapDataSource.class);
28  
29      private static JCO.Pool pool;
30      private static IRepository repository;
31  
32      private String username;
33      private String password;
34      private String host;
35      private String client;
36      private String systemNr;
37      private String language = "EN";
38      private int poolSize = 5;
39  
40      /**
41       * Gets the maximum time in seconds that this data source can wait
42       * while attempting to connect to a database.  A value of zero
43       * means that the timeout is the default system timeout
44       * if there is one; otherwise, it means that there is no timeout.
45       * When a <code>DataSource</code> object is created, the login timeout is
46       * initially zero.
47       *
48       * @return the data source login time limit
49       * @throws java.sql.SQLException if a database access error occurs.
50       * @see #setLoginTimeout
51       */
52      public int getLoginTimeout() throws SQLException {
53          return loginTimeout;
54      }
55  
56      /**
57       * <p>Sets the maximum time in seconds that this data source will wait
58       * while attempting to connect to a database.  A value of zero
59       * specifies that the timeout is the default system timeout
60       * if there is one; otherwise, it specifies that there is no timeout.
61       * When a <code>DataSource</code> object is created, the login timeout is
62       * initially zero.
63       *
64       * @param seconds the data source login time limit
65       * @throws java.sql.SQLException if a database access error occurs.
66       * @see #getLoginTimeout
67       */
68      public void setLoginTimeout(int seconds) throws SQLException {
69          this.loginTimeout = seconds;
70      }
71  
72      /**
73       * <p>Retrieves the log writer for this <code>DataSource</code>
74       * object.
75       * <p/>
76       * <p>The log writer is a character output stream to which all logging
77       * and tracing messages for this data source will be
78       * printed.  This includes messages printed by the methods of this
79       * object, messages printed by methods of other objects manufactured
80       * by this object, and so on.  Messages printed to a data source
81       * specific log writer are not printed to the log writer associated
82       * with the <code>java.sql.Drivermanager</code> class.  When a
83       * <code>DataSource</code> object is
84       * created, the log writer is initially null; in other words, the
85       * default is for logging to be disabled.
86       *
87       * @return the log writer for this data source or null if
88       *         logging is disabled
89       * @throws java.sql.SQLException if a database access error occurs
90       * @see #setLogWriter
91       */
92      public PrintWriter getLogWriter() throws SQLException {
93          return logWriter;
94      }
95  
96      /**
97       * <p>Sets the log writer for this <code>DataSource</code>
98       * object to the given <code>java.io.PrintWriter</code> object.
99       * <p/>
100      * <p>The log writer is a character output stream to which all logging
101      * and tracing messages for this data source will be
102      * printed.  This includes messages printed by the methods of this
103      * object, messages printed by methods of other objects manufactured
104      * by this object, and so on.  Messages printed to a data source-
105      * specific log writer are not printed to the log writer associated
106      * with the <code>java.sql.Drivermanager</code> class. When a
107      * <code>DataSource</code> object is created the log writer is
108      * initially null; in other words, the default is for logging to be
109      * disabled.
110      *
111      * @param out the new log writer; to disable logging, set to null
112      * @throws java.sql.SQLException if a database access error occurs
113      * @see #getLogWriter
114      */
115     public void setLogWriter(PrintWriter out) throws SQLException {
116         this.logWriter = out;
117     }
118 
119     protected Connection getSapConnection() throws SQLException {
120         validateConnectionProperties();
121         try {
122             JCO.Pool pool = getConnectionPool();
123             JCO.Client nativeConnection = JCO.getClient(pool.getName());
124             return new SapConnection(nativeConnection, getRepository());
125         } catch (Exception e) {
126             logger.error("Error creating SAP connection", e);
127             throw new SapConnectException(SqlErrorCodes.ErrorCreatingConnection, e.getMessage());
128         }
129     }
130 
131     private void validateConnectionProperties() throws SapConnectException {
132         try {
133             Validate.notEmpty(this.username);
134             Validate.notEmpty(this.password);
135             Validate.notEmpty(this.host);
136             Validate.notEmpty(this.client);
137             Validate.notEmpty(this.systemNr);
138         } catch (IllegalArgumentException e) {
139             throw new SapConnectException(SqlErrorCodes.MissingConnectionProperty, e.getMessage());
140         }
141     }
142 
143     private IRepository getRepository() {
144         getConnectionPool();
145         return repository;
146     }
147 
148     private synchronized JCO.Pool getConnectionPool() {
149         if (pool == null) {
150             String poolName = new StringBuffer("pool_").append(host).append(systemNr).append(client).toString();
151             pool = JCO.getClientPoolManager().getPool(poolName);
152             if (pool == null) {
153                 logger.info(new StringBuffer("Creating new pool ").append(poolName).append(" , max size: ").append(
154                         poolSize).toString());
155                 JCO.addClientPool(poolName, poolSize,// maximum number of connections
156                                   client, username, password, language, host, systemNr); // properties
157                 pool = JCO.getClientPoolManager().getPool(poolName);
158                 pool.setConnectionTimeout(60000);
159                 pool.setMaxWaitTime(60000);
160                 pool.setMaxConnections(poolSize * 2);
161             }
162             //pool.setResetOnRelease(true);
163             if (repository == null) {
164                 repository = JCO.createRepository("DefaultRepository", poolName);
165             }
166         }
167         return pool;
168     }
169 
170     /**
171      * <p>Attempts to establish a connection with the data source that
172      * this <code>DataSource</code> object represents.
173      *
174      * @return a connection to the data source
175      * @throws java.sql.SQLException if a database access error occurs
176      */
177     public Connection getConnection() throws SQLException {
178         return getSapConnection();
179     }
180 
181     /**
182      * <p>Attempts to establish a connection with the data source that
183      * this <code>DataSource</code> object represents.
184      *
185      * @param username the database user on whose behalf the connection is
186      *                 being made
187      * @param password the user's password
188      * @return a connection to the data source
189      * @throws java.sql.SQLException if a database access error occurs
190      */
191     public Connection getConnection(String username, String password) throws SQLException {
192         setUsername(username);
193         setPassword(password);
194         return getSapConnection();
195     }
196 
197     public void setProperties(String username, String password, String host, String client, String systemNr,
198                               String language) {
199         this.username = username;
200         this.password = password;
201         this.host = host;
202         this.client = client;
203         this.systemNr = systemNr;
204         this.language = language;
205     }
206 
207     public String getUsername() {
208         return username;
209     }
210 
211     public void setUsername(String username) {
212         this.username = username;
213     }
214 
215     public String getPassword() {
216         return password;
217     }
218 
219     public void setPassword(String password) {
220         this.password = password;
221     }
222 
223     public String getHost() {
224         return host;
225     }
226 
227     public void setHost(String host) {
228         this.host = host;
229     }
230 
231     public String getClient() {
232         return client;
233     }
234 
235     public void setClient(String client) {
236         this.client = client;
237     }
238 
239     public String getSystemNr() {
240         return systemNr;
241     }
242 
243     public void setSystemNr(String systemNr) {
244         this.systemNr = systemNr;
245     }
246 
247     public String getLanguage() {
248         return language;
249     }
250 
251     public void setLanguage(String language) {
252         this.language = language;
253     }
254 }