1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.millscript.millscript.loaders;
23
24 import org.millscript.commons.vfs.VFile;
25 import org.millscript.millscript.alert.Alerts;
26 import org.millscript.millscript.conf.functions.DatabaseLockfileFunction;
27 import org.millscript.millscript.datatypes.DatabaseSource;
28
29 import java.io.File;
30 import java.io.IOException;
31 import java.util.Properties;
32
33 import org.postgresql.jdbc3.Jdbc3PoolingDataSource;
34
35 /**
36 * This class implements a JDBC connection file loader. The idea is to take a
37 * Java properties file containing all the properties required to establish a
38 * JDBC connection and construct a new DataSource. The Java properties file is
39 * expected to look something like:
40 * <pre>
41 * data.source.name = The name of this DataSource
42 * host = ahost.somewhere.org
43 * port = 5432
44 * username = testuser
45 * password = testpassword
46 * db.name = test
47 * max.connections = 10
48 * </pre>
49 * where <code>port</code> and <code>max.connections</code> are optional.
50 *
51 * @see org.millscript.millscript.loaders.ValueLoader
52 * @see javax.sql.DataSource
53 * @since 9.6.4
54 */
55 public class JdbcConnectionLoader extends ValueLoader {
56
57 /**
58 * The Properties object containing the required settings to construct a
59 * database connection pool.
60 */
61 private static Properties connectionProperties = new Properties();
62
63 /**
64 * Tests if the specified key is defined in the connection properties.
65 *
66 * @param key a key in the connection properties
67 * @return <code>true</code> if the connection file defines the specified
68 * key, <code>false</code> otherwise
69 */
70 private boolean containsKey( final String key ) {
71 return connectionProperties.containsKey( key );
72 }
73
74 /**
75 * Returns the value associated with the specified key, generating a Mishap
76 * if the key is not defined.
77 *
78 * @param key a key in the connection properties
79 * @return the string containing the value for the specified key
80 */
81 private String getStringValue( final String key ) {
82
83 if ( !containsKey( key ) ) {
84
85 throw(
86 Alerts.compile(
87 "Required JDBC connection properties must be defined",
88 "All required properties must be defined"
89 ).
90 culprit( "file", getOrigin() ).
91 culprit( "key", key ).
92 mishap()
93 );
94
95 }
96
97 String value = connectionProperties.getProperty( key );
98
99 if ( value == null ) {
100 return "";
101 }
102
103 return value;
104
105 }
106
107 /**
108 * Returns the value, as an int, associated with the specified key,
109 * generating a Mishap if the key is not defined.
110 *
111 * @param key a key in the connection properties
112 * @return an int containing the value for the specified key
113 */
114 private int getIntValue( final String key ) {
115
116 String value = getStringValue( key );
117
118 try {
119 return Integer.parseInt( value );
120 } catch ( NumberFormatException ex ) {
121 throw(
122 Alerts.compile(
123 "JDBC connection property must be an integer",
124 "Cannot convert the supplied value to an int"
125 ).
126 culprit( "file", getOrigin() ).
127 culprit( "key", key ).
128 culprit( "value", value ).
129 mishap()
130 );
131 }
132
133 }
134
135 /**
136 * @see org.millscript.millscript.loaders.Loader#loadValue()
137 */
138 @Override
139 public Object loadValue() throws IOException {
140
141 if ( this.entry instanceof VFile && this.entry.exists() ) {
142 connectionProperties.load( ((VFile) entry).getInputStream() );
143 } else {
144 throw(
145 Alerts.compile(
146 "Inventory entry is not a file",
147 "JDBC connection loader can only be used to load files"
148 ).culprit( "entry", this.entry ).mishap()
149 );
150 }
151
152 Jdbc3PoolingDataSource jdbcsource = new Jdbc3PoolingDataSource();
153
154
155
156
157
158
159 if ( containsKey( "port" ) ) {
160 jdbcsource.setPortNumber( getIntValue( "port" ) );
161 }
162
163
164 if ( containsKey( "max.connections" ) ) {
165 jdbcsource.setMaxConnections( getIntValue( "max.connections" ) );
166 }
167
168
169
170
171
172
173 jdbcsource.setDataSourceName( getStringValue( "data.source.name" ) );
174
175
176 jdbcsource.setServerName( getStringValue( "host" ) );
177
178
179 jdbcsource.setDatabaseName( getStringValue( "db.name" ) );
180
181
182 jdbcsource.setUser( getStringValue( "username" ) );
183
184
185 jdbcsource.setPassword( getStringValue( "password" ) );
186
187
188 String templateLF = this.pack.getConfig().getProperty( DatabaseLockfileFunction.KEY );
189 File lf = null;
190
191 if ( !templateLF.equals( "" ) ) {
192 templateLF = templateLF.replaceAll( "\\$\\{DATABASENAME\\}", getStringValue( "db.name" ) );
193 lf = new File( templateLF );
194 }
195
196 return new DatabaseSource( jdbcsource.getDataSourceName(), jdbcsource, lf );
197
198 }
199
200 }