/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