|
/usr/java/lib/xflow1.2.1/src/xflow/util/Persistence.java
|
1 /*
2 * ====================================================================
3 *
4 * XFLOW - Process Management System
5 * Copyright (C) 2003 Rob Tan
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions, and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions, and the disclaimer that follows
17 * these conditions in the documentation and/or other materials
18 * provided with the distribution.
19 *
20 * 3. The name "XFlow" must not be used to endorse or promote products
21 * derived from this software without prior written permission. For
22 * written permission, please contact rcktan@yahoo.com
23 *
24 * 4. Products derived from this software may not be called "XFlow", nor
25 * may "XFlow" appear in their name, without prior written permission
26 * from the XFlow Project Management (rcktan@yahoo.com)
27 *
28 * In addition, we request (but do not require) that you include in the
29 * end-user documentation provided with the redistribution and/or in the
30 * software itself an acknowledgement equivalent to the following:
31 * "This product includes software developed by the
32 * XFlow Project (http://xflow.sourceforge.net/)."
33 * Alternatively, the acknowledgment may be graphical using the logos
34 * available at http://xflow.sourceforge.net/
35 *
36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39 * DISCLAIMED. IN NO EVENT SHALL THE XFLOW AUTHORS OR THE PROJECT
40 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 *
49 * ====================================================================
50 * This software consists of voluntary contributions made by many
51 * individuals on behalf of the XFlow Project and was originally
52 * created by Rob Tan (rcktan@yahoo.com)
53 * For more information on the XFlow Project, please see:
54 * <http://xflow.sourceforge.net/>.
55 * ====================================================================
56 */
57 package xflow.util;
58
59 import com.ibatis.common.resources.Resources;
60 import com.ibatis.sqlmap.client.SqlMapClient;
61 import com.ibatis.sqlmap.client.SqlMapClientBuilder;
62 import net.sf.cglib.proxy.Enhancer;
63 import net.sf.cglib.proxy.MethodInterceptor;
64 import org.apache.log4j.Logger;
65 import xflow.server.controller.*;
66
67 import javax.naming.InitialContext;
68 import javax.sql.DataSource;
69 import java.io.IOException;
70 import java.io.Reader;
71 import java.sql.Connection;
72 import java.sql.ResultSet;
73 import java.sql.SQLException;
74 import java.sql.Statement;
75 import java.util.Hashtable;
76 import java.util.Map;
77
78 public class Persistence {
79 public static final String DB_PROPERTIES = "xflow.properties";
80 private static Object guard = new Object();
81 private static InitialContext iniCtx;
82 private static DataSource ds;
83 static Logger log = Logger.getLogger(Persistence.class);
84
85 static public void init () {
86
87 }
88
89 /* static private void _init () {
90
91
92 Connection conn = null;
93 Statement s = null;
94
95 // Create all the necessary tables used by xflow
96 try {
97 // iniCtx = new InitialContext();
98 // ds = (DataSource)iniCtx.lookup(XflowConfig.XFLOW_DATASOURCE());
99 ds = getSqlMap().getDataSource();
100 }catch( Exception e ){
101 log.error ("Cannot get datasource" + XflowConfig.XFLOW_DATASOURCE(), e );
102 return;
103 }
104 try{
105 conn = ds.getConnection();
106 s = conn.createStatement();
107 String dbCreateScriptResource = XflowConfig.DB_CREATE_SCRIPT();
108 URL url = Persistence.class.getClassLoader().getResource( dbCreateScriptResource );
109 if( url == null ){
110 url = Thread.currentThread().getContextClassLoader().getResource( dbCreateScriptResource );
111 }
112 if( url != null ){
113 String buf = readResource( url );
114 String[] statements = buf.split( ";" );
115 for (int i = 0; i < statements.length; i++) {
116 String statement = statements[i];
117 log.info( "Executing:" + statement );
118 s.execute ( statement );
119 }
120
121 log.info ("XFlow Tables initialized");
122 }else{
123 throw new Exception( "Resource " + dbCreateScriptResource + " not found" );
124 }
125 } catch (Exception e) {
126 log.info (e.getMessage());
127 log.info ("updating workflow table");
128 try {
129 s.execute ("alter table workflow add column status varchar(32)");
130 s.execute ("alter table workflow add column parentWorkflowId int");
131 s.execute ("alter table inbox add column timeout bit");
132 log.info ("workflow table updated");
133 } catch (Exception e2) {
134 log.info ("workflow table up-to-date");
135 }
136 } finally {
137 try {
138 closeAll( null, s, conn );
139 } catch (SQLException e) {
140 log.error( "", e );
141 }
142 }
143 }*/
144
145 /*private static String readResource(URL url) throws IOException {
146 StringBuffer buf = new StringBuffer();
147 InputStream is = url.openStream();
148 InputStreamReader r = new InputStreamReader( is );
149 char[] charBuf = new char[ 2048 ];
150 int len = -1;
151 while( ( len = r.read( charBuf ) ) != -1 ){
152 buf.append( charBuf, 0, len );
153 }
154 r.close();
155 return buf.toString();
156 }*/
157
158
159
160 /* public static void execute( JDBCWork work ) throws Exception{
161 //later will deal with thread local variables to reuse connection and env
162 JDBCWork.JDBCEnv env = new JDBCWork.JDBCEnv();
163 env.connection = getConnection();
164 try{
165 work.execute( env );
166 }finally{
167 closeAll( env.resultSet, env.statement, env.connection );
168 }
169 }*/
170
171 public static void execute( IBatisWork work ) throws Exception{
172 //later will deal with thread local variables to reuse connection and env
173 getWorkExecutor().execute( work );
174 }
175
176
177 private static SqlMapClient sqlMap = null;
178
179 public static SqlMapClient getSqlMap() throws IOException {
180 synchronized( guard ){
181 if( sqlMap == null ){
182 sqlMap = initSQLSqlMap();
183 }
184 return sqlMap;
185 }
186 }
187
188 private static SqlMapClient initSQLSqlMap() throws IOException {
189 String resource = "xflow/server/controller/sqlmap.xml" ;
190 Reader reader = Resources.getResourceAsReader (resource);
191 SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
192 return sqlMap;
193 }
194
195
196 public static Connection getConnection () throws Exception {
197 synchronized( guard ){
198 if( ds == null){
199 ds = getSqlMap().getDataSource();
200 }
201
202 if( ds == null ){
203 throw new SQLException( "Cannot create Data Source");
204 }
205 return ds.getConnection();
206 }
207 }
208
209 public static void closeAll( ResultSet rs, Statement st, Connection c) throws SQLException {
210 try{
211 if( rs != null ) rs.close();
212 }finally{
213 try{
214 if( st != null ) st.close();
215 }finally{
216 if( c != null ) c.close();
217 }
218 }
219 }
220
221
222 private static WorkflowP workflowP = null;
223 private static WorkItemP workItemP = null;
224 private static InboxP inboxP = null;
225 private static DirectedGraphP directedGraphP = null;
226 private static WorkExecutor workExecutor = null;
227 private static ProcessStack processStack = null;
228 private static WaitingP waitingP = null;
229
230 public static WorkExecutor getWorkExecutor() {
231 synchronized( guard ){
232 if( workExecutor == null ){
233 workExecutor = (WorkExecutor) enhanceInstanceOfClass( WorkExecutor.class);
234 }
235 return workExecutor;
236 }
237
238 }
239
240 public static WaitingP getWaitingP() {
241 synchronized( guard ){
242 if( waitingP == null ){
243 waitingP = (WaitingP) enhanceInstanceOfClass( WaitingP.class );
244 }
245 return waitingP;
246 }
247
248 }
249
250 public static DirectedGraphP getDirectGraphP(){
251 synchronized( guard ){
252 if( directedGraphP == null){
253 directedGraphP = (DirectedGraphP) enhanceInstanceOfClass( DirectedGraphP.class);
254 }
255 return directedGraphP;
256 }
257
258 }
259
260
261 public static WorkflowP getWorkflowP() {
262 synchronized( guard ){
263 if( workflowP == null ){
264 workflowP = (WorkflowP) enhanceInstanceOfClass( WorkflowP.class );
265 }
266 return workflowP;
267 }
268
269 }
270
271 public static WorkItemP getWorkItemP() {
272 synchronized( guard ){
273 if( workItemP == null ){
274 workItemP = (WorkItemP) enhanceInstanceOfClass( WorkItemP.class );
275 }
276 return workItemP;
277 }
278
279 }
280
281 public static InboxP getInboxP() {
282 synchronized( guard ){
283 if( inboxP == null ){
284 inboxP = (InboxP) enhanceInstanceOfClass( InboxP.class );
285 }
286 return inboxP;
287 }
288
289 }
290
291 public static ProcessStack getProcessStack(){
292 synchronized( guard ){
293 if( processStack == null ){
294 processStack = (ProcessStack) enhanceInstanceOfClass(ProcessStack.class );
295 }
296 return processStack;
297 }
298 }
299
300
301 static ThreadLocal threadSqlMap = new ThreadLocal(){
302 protected Object initialValue() {
303 return null;
304 }
305 };
306
307 public static SqlMapClient getThreadSqlMapSession(){
308 return (SqlMapClient) threadSqlMap.get();
309 }
310
311
312 private static Map enhancers = new Hashtable();
313 private static MethodInterceptor ibatisCallback = new IBatisMethodInterceptor();
314
315
316 public static Object enhanceInstanceOfClass( Class clazz ) {
317 Enhancer en = ( Enhancer ) enhancers.get( clazz.getName() );
318 if( en == null ){
319 if( log.isDebugEnabled() ){
320 log.debug( "Create Enhancer for class::" + clazz.getName() );
321 }
322 en = new Enhancer();
323 en.setSuperclass( clazz );
324 en.setCallbacks( new MethodInterceptor[]{ ibatisCallback} );
325 // en.setCallbacks( new MethodInterceptor[]{ new IBatisMethodInterceptor()} );
326 enhancers.put( clazz.getName(), en );
327 }
328 return en.create();
329 }
330
331
332
333 }
334
335