KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > genimen > djeneric > repository > rdbms > RdbmsPersistenceManager


1 /*
2  * Copyright (c) 2001-2005 by Genimen BV (www.genimen.com) All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, is permitted provided that the following conditions are met: -
6  * Redistributions of source code must retain the above copyright notice, this
7  * list of conditions and the following disclaimer. - Redistributions in binary
8  * form must reproduce the above copyright notice, this list of conditions and
9  * the following disclaimer in the documentation and/or other materials
10  * provided with the distribution. - All advertising materials mentioning
11  * features or use of this software must display the following acknowledgment:
12  * "This product includes Djeneric." - Products derived from this software may
13  * not be called "Djeneric" nor may "Djeneric" appear in their names without
14  * prior written permission of Genimen BV. - Redistributions of any form
15  * whatsoever must retain the following acknowledgment: "This product includes
16  * Djeneric."
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL GENIMEN BV, DJENERIC.ORG, OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */

30 package com.genimen.djeneric.repository.rdbms;
31
32 import java.io.IOException JavaDoc;
33 import java.sql.Connection JavaDoc;
34 import java.sql.DriverManager JavaDoc;
35 import java.sql.ResultSet JavaDoc;
36 import java.sql.SQLException JavaDoc;
37 import java.text.SimpleDateFormat JavaDoc;
38 import java.util.ArrayList JavaDoc;
39 import java.util.EmptyStackException JavaDoc;
40 import java.util.HashMap JavaDoc;
41 import java.util.Stack JavaDoc;
42
43 import javax.naming.Context JavaDoc;
44 import javax.naming.InitialContext JavaDoc;
45 import javax.sql.DataSource JavaDoc;
46
47 import com.genimen.djeneric.language.Messages;
48 import com.genimen.djeneric.repository.DjContextManager;
49 import com.genimen.djeneric.repository.DjExtent;
50 import com.genimen.djeneric.repository.DjIdProvider;
51 import com.genimen.djeneric.repository.DjMessenger;
52 import com.genimen.djeneric.repository.DjModelView;
53 import com.genimen.djeneric.repository.DjPersistenceManager;
54 import com.genimen.djeneric.repository.DjProperty;
55 import com.genimen.djeneric.repository.DjRelation;
56 import com.genimen.djeneric.repository.DjRepositoryDescriptor;
57 import com.genimen.djeneric.repository.DjSession;
58 import com.genimen.djeneric.repository.exceptions.CatalogException;
59 import com.genimen.djeneric.repository.exceptions.DjenericException;
60 import com.genimen.djeneric.repository.exceptions.LoadModelException;
61 import com.genimen.djeneric.util.DjLogger;
62
63 /**
64  * Description of the Class
65  *
66  * @author Wido Riezebos @created 27 mei 2002
67  */

68 public class RdbmsPersistenceManager extends DjPersistenceManager
69 {
70   private int _maxConnectionPoolSize = 20;
71
72   public final static String JavaDoc OBJECT_TYPE_COLUMN = "_OBJTYPE";
73
74   /**
75    * Description of the Field
76    */

77   public final static String JavaDoc CONTEXT_TABLE = "dj_contexts";
78   /**
79    * Description of the Field
80    */

81   public final static String JavaDoc USER_TABLE = "dj_users";
82   /**
83    * Description of the Field
84    */

85   public final static String JavaDoc USER_CTX_TABLE = "dj_usr_ctx";
86   /**
87    * Description of the Field
88    */

89   public final static String JavaDoc USER_VWS_TABLE = "dj_usr_vws";
90   /**
91    * Description of the Field
92    */

93   public final static String JavaDoc VIEW_TABLE = "dj_views";
94   /**
95    * Description of the Field
96    */

97   public final static String JavaDoc MODEL_TABLE = "dj_model";
98   /**
99    * Description of the Field
100    */

101   public final static String JavaDoc POLYMORPH_TABLE = "dj_polymorph";
102   /**
103    * Description of the Field
104    */

105   public final static String JavaDoc INTERNAL_IDS_TABLE = "dj_ids";
106
107   /**
108    * Description of the Field
109    */

110   public final static String JavaDoc INTERNAL_TYPE_COLUMN = "table_alias";
111   /**
112    * Description of the Field
113    */

114   public final static String JavaDoc INTERNAL_CONTEXT_COLUMN = "context_id";
115
116   /**
117    * Description of the Field
118    */

119   public final static String JavaDoc CONTEXT_PARAM_NAME = "_dj_context_id_";
120   /**
121    * Description of the Field
122    */

123   public final static int LOCK_STRING_MAX_LENGTH = 50;
124
125   private int _sqlTranslationMode;
126   HashMap JavaDoc _cachedStatements = new HashMap JavaDoc();
127
128   // This holds the value of the current lock on the modeler
129
// aquired by this manager.
130
private String JavaDoc _modelLockTag = null;
131
132   Stack JavaDoc _connectionPool = new Stack JavaDoc();
133
134   /**
135    * Constructor for the RdbmsPersistenceManager object
136    *
137    * @param mainFrame
138    * Description of the Parameter
139    * @param rdesc
140    * Description of the Parameter
141    * @exception DjenericException
142    * Description of the Exception
143    */

144   public RdbmsPersistenceManager(DjMessenger messenger, DjRepositoryDescriptor rdesc) throws DjenericException
145   {
146     super(messenger, rdesc);
147     sharedInit();
148     construct();
149   }
150
151   protected void sharedInit()
152   {
153     setTranslationMode(SqlXlator.TRANSLATE_TO_MAPPING);
154   }
155
156   /**
157    * Constructor for the RdbmsPersistenceManager object, using the supplied
158    * repository user and password. If user is null the user specified in the
159    * repository descriptor is used. If password is null the password specified
160    * in the repository descriptor is used.
161    *
162    * @param mainFrame
163    * Description of the Parameter
164    * @param rdesc
165    * Description of the Parameter
166    * @exception DjenericException
167    * Description of the Exception
168    */

169   public RdbmsPersistenceManager(DjMessenger messenger, DjRepositoryDescriptor rdesc, String JavaDoc repositoryUser,
170                                  String JavaDoc repositoryPassword) throws DjenericException
171   {
172     super(messenger, rdesc);
173     sharedInit();
174     if (repositoryUser != null) setRepositoryUser(repositoryUser);
175     if (repositoryPassword != null) setRepositoryPassword(repositoryPassword);
176     construct();
177   }
178
179   protected void construct() throws DjenericException
180   {
181     loadModel();
182   }
183
184   /**
185    * Returns the inPolymorphMode of the RdbmsPersistenceManager object
186    *
187    * @return The inPolymorphMode value
188    */

189   public boolean isInPolymorphMode()
190   {
191     return (getTranslationMode() == SqlXlator.TRANSLATE_TO_MAPPING);
192   }
193
194   /**
195    * Sets the translationMode of the RdbmsPersistenceManager object
196    *
197    * @param tp
198    * The new translationMode value
199    */

200   public void setTranslationMode(int tp)
201   {
202     _sqlTranslationMode = tp;
203   }
204
205   /**
206    * Returns the translationMode of the RdbmsPersistenceManager object
207    *
208    * @return The translationMode value
209    */

210   public int getTranslationMode()
211   {
212     return _sqlTranslationMode;
213   }
214
215   // We are deliberately NOT using a Session here because when this method is
216
// called
217
// the manager might not be set up completely and thus might interfere with
218
// Session logic
219
// that needs a initialized manager to work properly
220
/**
221    * Description of the Method
222    *
223    * @return Description of the Return Value
224    * @exception DjenericException
225    * Description of the Exception
226    */

227   protected String JavaDoc retrieveModelXml() throws DjenericException
228   {
229     Connection JavaDoc conn = getConnection();
230     String JavaDoc result = "";
231     try
232     {
233       SqlStatement stmt = new SqlStatement(conn, "select metamodel from " + MODEL_TABLE);
234       ResultSet JavaDoc rs = stmt.executeQuery();
235       if (rs.next())
236       {
237         result = new String JavaDoc(SqlStatement.getBlob(rs, "metamodel"));
238       }
239       rs.close();
240       stmt.close();
241     }
242     catch (SQLException JavaDoc sqe)
243     {
244       throw new LoadModelException(sqe);
245     }
246     catch (IOException JavaDoc iox)
247     {
248       throw new CatalogException(iox);
249     }
250     finally
251     {
252       try
253       {
254         releaseToPool(conn);
255       }
256       catch (SQLException JavaDoc se)
257       {
258         throw new CatalogException(se);
259       }
260       if (shouldTrace(TRACE_INTERNAL)) trace("Model retrieved");
261     }
262     return result;
263   }
264
265   public void loadModel() throws DjenericException
266   {
267     super.loadModel();
268
269     // cached statements might have become invalid: clear the cache now
270
_cachedStatements = new HashMap JavaDoc();
271   }
272
273   /**
274    * Description of the Method
275    *
276    * @param xml
277    * Description of the Parameter
278    * @exception DjenericException
279    * Description of the Exception
280    */

281   protected void storeModelXml(String JavaDoc xml) throws DjenericException
282   {
283     try
284     {
285       RdbmsSession session = (RdbmsSession) createSession();
286       try
287       {
288         SqlStatement stmt = session.getInternalSqlStatement("delete from " + MODEL_TABLE);
289         stmt.executeUpdate();
290
291         stmt = session.getInternalSqlStatement("insert into " + MODEL_TABLE
292                                                + "(metamodel, locked_by) values(:metamodel, :lockedBy)");
293         stmt.setBlob("metamodel", xml, DjPersistenceManager.ENCODING_METHOD);
294         stmt.setString("lockedBy", _modelLockTag);
295         stmt.executeUpdate();
296         session.commit();
297         if (shouldTrace(TRACE_INTERNAL)) trace("Model stored");
298       }
299       finally
300       {
301         session.close();
302       }
303     }
304     catch (SQLException JavaDoc x)
305     {
306       throw new DjenericException(x);
307     }
308   }
309
310   /**
311    * Returns the views of the RdbmsPersistenceManager object
312    *
313    * @return The views value
314    * @exception DjenericException
315    * Description of the Exception
316    */

317   public DjModelView[] getViews() throws DjenericException
318   {
319     try
320     {
321       RdbmsSession session = (RdbmsSession) createSession();
322       ArrayList JavaDoc result = new ArrayList JavaDoc();
323
324       try
325       {
326         SqlStatement stmt = ((RdbmsSession) session).getInternalSqlStatement("select id, code, metaview " + "from "
327                                                                              + VIEW_TABLE + " mvw "
328                                                                              + "order by mvw.code ");
329         ResultSet JavaDoc rs = stmt.executeQuery();
330         while (rs.next())
331         {
332           DjModelView vw = new RdbmsModelView(this, rs.getLong("id"), rs.getString("code"), new String JavaDoc(SqlStatement
333               .getBlob(rs, "metaview")));
334           result.add(vw);
335         }
336         rs.close();
337         stmt.close();
338         if (shouldTrace(TRACE_INTERNAL)) trace("Views retrieved");
339       }
340       finally
341       {
342         session.close();
343       }
344
345       return (DjModelView[]) result.toArray(new DjModelView[0]);
346     }
347     catch (SQLException JavaDoc x)
348     {
349       throw new DjenericException(x);
350     }
351     catch (IOException JavaDoc x)
352     {
353       throw new DjenericException(x);
354     }
355   }
356
357   /**
358    * Description of the Method
359    *
360    * @exception DjenericException
361    * Description of the Exception
362    */

363   public void login() throws DjenericException
364   {
365     super.login();
366
367     // Clear the pool! Previous connections are still using the old un/pw!
368
// If the user was changed, this will lead to unexpected behaviour!
369
// so:
370
clearConnectionPool();
371   }
372
373   /**
374    * Description of the Method
375    */

376   public void clearConnectionPool()
377   {
378     while (_connectionPool.size() > 0)
379     {
380       try
381       {
382         ((Connection JavaDoc) _connectionPool.pop()).close();
383       }
384       catch (EmptyStackException JavaDoc esx)
385       {
386         // Unlikely to happen; but if:
387
// Another thread was quicker; ignore this one
388
}
389       catch (SQLException JavaDoc x)
390       {
391         DjLogger.log(x);
392       }
393     }
394   }
395
396   /**
397    * Description of the Method
398    */

399   public void close()
400   {
401     try
402     {
403       if (isModelLocked()) unlockModel();
404       if (shouldTrace(TRACE_INTERNAL)) trace("Persistence manager closed");
405     }
406     catch (CatalogException x)
407     {
408       DjLogger.log(x);
409     }
410     clearConnectionPool();
411   }
412
413   private boolean _isolationProblemEncountered = false;
414
415   /**
416    * Returns the connection of the RdbmsPersistenceManager object
417    *
418    * @return The connection value
419    * @exception DjenericException
420    * Description of the Exception
421    */

422   protected Connection JavaDoc getConnection() throws DjenericException
423   {
424     try
425     {
426       if (!isRepositoryUserKnown())
427       {
428         login();
429       }
430
431       // We deliberately use the catch(EmptyStackException) here to make sure
432
// we are thread safe. If we check with isEmpty() first we are not thread
433
// safe anymore. Therefore:
434

435       try
436       {
437         Connection JavaDoc conn = (Connection JavaDoc) _connectionPool.pop();
438         if (shouldTrace(TRACE_INTERNAL)) trace("Connection fetched from connection pool");
439         return conn;
440       }
441       catch (EmptyStackException JavaDoc esx)
442       {
443         // Ok, then create a new one below:
444
}
445
446       Connection JavaDoc conn;
447       if (getCurrentRepository().isDatasource())
448       {
449         Context JavaDoc initContext = new InitialContext JavaDoc();
450         Context JavaDoc envContext = (Context JavaDoc) initContext.lookup("java:comp/env");
451         DataSource JavaDoc ds = (DataSource JavaDoc) envContext.lookup(getCurrentRepository().getUrl());
452         conn = ds.getConnection();
453       }
454       else
455       {
456         Class.forName(getCurrentRepository().getDriver());
457         conn = DriverManager.getConnection(getCurrentRepository().getUrl(), getRepositoryUser(),
458                                            getRepositoryPassword());
459       }
460       conn.setAutoCommit(false);
461       try
462       {
463         conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
464       }
465       catch (SQLException JavaDoc x)
466       {
467         if (!_isolationProblemEncountered) DjLogger.log(Messages.getString("RdbmsPersistenceManager.IsolationLevel", x
468             .getMessage()));
469         _isolationProblemEncountered = true;
470       }
471       if (shouldTrace(TRACE_INTERNAL)) trace("New connection created");
472       return conn;
473     }
474     catch (Exception JavaDoc x)
475     {
476       throw new DjenericException(x);
477     }
478   }
479
480   /**
481    * Description of the Method
482    *
483    * @param conn
484    * Description of the Parameter
485    * @exception SQLException
486    * Description of the Exception
487    */

488   protected void releaseToPool(Connection JavaDoc conn) throws SQLException JavaDoc
489   {
490     if (conn == null) return;
491     if (_connectionPool.size() < _maxConnectionPoolSize)
492     {
493       // make sure there is nothing left in a current transaction that will
494
// become part of a new transaction otherwise
495
conn.rollback();
496       _connectionPool.push(conn);
497       if (shouldTrace(TRACE_INTERNAL)) trace("Connection released to pool (poolsize = " + _connectionPool.size() + ")");
498     }
499     else
500     {
501       // discard it then, we've got enough pooled.
502
conn.close();
503       if (shouldTrace(TRACE_INTERNAL)) trace("Connection discarded (poolsize = " + _connectionPool.size() + ")");
504     }
505   }
506
507   /**
508    * Description of the Method
509    *
510    * @return Description of the Return Value
511    * @exception DjenericException
512    * Description of the Exception
513    */

514   public DjSession createSession() throws DjenericException
515   {
516     RdbmsSession ses = new RdbmsSession(this);
517     ses.setCommitAllowed(isCommitAllowed());
518     return ses;
519   }
520
521   /**
522    * Description of the Method
523    *
524    * @param sql
525    * Description of the Parameter
526    * @return Description of the Return Value
527    * @exception DjenericException
528    * Description of the Exception
529    */

530   public String JavaDoc external2internalStatement(String JavaDoc sql) throws DjenericException
531   {
532     try
533     {
534       String JavaDoc prevOne = (String JavaDoc) _cachedStatements.get(sql);
535       if (prevOne != null) return prevOne;
536
537       SqlXlator xlator = new SqlXlator(this, getCurrentContext());
538       xlator.setTranslationMode(_sqlTranslationMode);
539       String JavaDoc result = xlator.translate(sql);
540       _cachedStatements.put(sql, result);
541       return result;
542     }
543     catch (Throwable JavaDoc x)
544     {
545       System.err.println(sql);
546       throw new DjenericException(x);
547     }
548   }
549
550   /**
551    * Description of the Method
552    *
553    * @param sql
554    * Description of the Parameter
555    * @param metaDataColumnUsages
556    * Description of the Parameter
557    * @return Description of the Return Value
558    * @exception DjenericException
559    * Description of the Exception
560    */

561   public String JavaDoc external2internalStatement(String JavaDoc sql, ArrayList JavaDoc metaDataColumnUsages) throws DjenericException
562   {
563     try
564     {
565       SqlXlator xlator = new SqlXlator(this, getCurrentContext());
566       xlator.setTranslationMode(_sqlTranslationMode);
567       xlator.setGatherMetaData(true);
568
569       metaDataColumnUsages.clear();
570       String JavaDoc result = xlator.translate(sql);
571       metaDataColumnUsages.addAll(xlator.getMetaData());
572
573       return result;
574     }
575     catch (Exception JavaDoc x)
576     {
577       System.err.println(sql);
578       throw new DjenericException(x);
579     }
580   }
581
582   /**
583    * Description of the Method
584    *
585    * @return Description of the Return Value
586    * @exception DjenericException
587    * Description of the Exception
588    */

589   public DjModelView createModelView()
590   {
591     return new RdbmsModelView(this);
592   }
593
594   /**
595    * Description of the Method
596    *
597    * @param mgr
598    * Description of the Parameter
599    * @return Description of the Return Value
600    */

601   public DjContextManager createContextManager(DjPersistenceManager mgr)
602   {
603     return new RdbmsContextManager(mgr);
604   }
605
606   /**
607    * Description of the Method
608    *
609    * @param objectType
610    * Description of the Parameter
611    * @param name
612    * Description of the Parameter
613    * @param alias
614    * Description of the Parameter
615    * @param internalCode
616    * Description of the Parameter
617    * @param title
618    * Description of the Parameter
619    * @param nameSingular
620    * Description of the Parameter
621    * @param namePlural
622    * Description of the Parameter
623    * @return Description of the Return Value
624    */

625   public DjExtent createExtent(String JavaDoc objectType, String JavaDoc name, String JavaDoc alias, String JavaDoc internalCode, String JavaDoc title,
626                                String JavaDoc nameSingular, String JavaDoc namePlural)
627   {
628     return new RdbmsExtent(objectType, name, alias, internalCode, title, nameSingular, namePlural);
629   }
630
631   /**
632    * Description of the Method
633    *
634    * @return Description of the Return Value
635    */

636   public DjIdProvider createIdProvider()
637   {
638     return new RdbmsIdProvider();
639   }
640
641   /**
642    * Description of the Method
643    *
644    * @param cacheSize
645    * Description of the Parameter
646    * @return Description of the Return Value
647    */

648   public DjIdProvider createIdProvider(int cacheSize)
649   {
650     return new RdbmsIdProvider(cacheSize);
651   }
652
653   /**
654    * Description of the Method
655    *
656    * @param name
657    * Description of the Parameter
658    * @param masterExtent
659    * Description of the Parameter
660    * @param detailExtent
661    * Description of the Parameter
662    * @param detailProperty
663    * Description of the Parameter
664    * @param isContainedRelation
665    * Description of the Parameter
666    * @param description
667    * Description of the Parameter
668    * @return Description of the Return Value
669    */

670   public DjRelation createRelation(String JavaDoc name, DjExtent masterExtent, DjExtent detailExtent,
671                                    DjProperty detailProperty, boolean isContainedRelation, String JavaDoc description)
672   {
673     return new DjRelation(name, masterExtent, detailExtent, detailProperty, isContainedRelation, description);
674   }
675
676   /**
677    * Returns the modelLocked of the RdbmsPersistenceManager object
678    *
679    * @return The modelLocked value
680    */

681   public boolean isModelLocked()
682   {
683     return _modelLockTag != null;
684   }
685
686   /**
687    * Returns the currentLockTag of the RdbmsPersistenceManager object
688    *
689    * @return The currentLockTag value
690    * @exception CatalogException
691    * Description of the Exception
692    */

693   public String JavaDoc getCurrentLockTag() throws CatalogException
694   {
695     try
696     {
697       RdbmsSession session = (RdbmsSession) createSession();
698       try
699       {
700         SqlStatement stmt = session.getInternalSqlStatement("select locked_by from " + MODEL_TABLE);
701
702         String JavaDoc lockString = null;
703         ResultSet JavaDoc rs = stmt.executeQuery();
704         if (rs.next()) lockString = rs.getString("locked_by");
705         rs.close();
706         stmt.close();
707         return lockString;
708       }
709       finally
710       {
711         session.close();
712       }
713     }
714     catch (Exception JavaDoc x)
715     {
716       throw new CatalogException(x);
717     }
718   }
719
720   /**
721    * Description of the Method
722    *
723    * @exception CatalogException
724    * Description of the Exception
725    */

726   public void lockModel() throws CatalogException
727   {
728     boolean lockFailed = false;
729     String JavaDoc msg = null;
730     try
731     {
732       RdbmsSession session = (RdbmsSession) createSession();
733       try
734       {
735         SqlStatement stmt = session.getInternalSqlStatement("update " + MODEL_TABLE + " set locked_by = :lockedBy "
736                                                             + " where (locked_by is null or locked_by = :lockedBy)");
737
738         String JavaDoc lockString;
739         if (_modelLockTag != null) lockString = _modelLockTag;
740         else
741         {
742           SimpleDateFormat JavaDoc sf = new SimpleDateFormat JavaDoc("dd-MM-yyyy HH:mm:ss");
743           String JavaDoc ts = sf.format(new java.util.Date JavaDoc(System.currentTimeMillis()));
744           lockString = System.getProperty("user.name", "anonymous") + " at " + ts;
745           if (lockString.length() > LOCK_STRING_MAX_LENGTH) lockString = lockString
746               .substring(0, LOCK_STRING_MAX_LENGTH);
747         }
748
749         stmt.setString("lockedBy", lockString);
750         int recsHit = stmt.executeUpdate();
751         stmt.close();
752
753         // Check to see if there is a model. In that case insert an empty model
754
// with the new lock. We know that this algorithm is NOT bullet proof:
755
// It is in theory possible that two processes can insert a model at
756
// the same time: if both run the select count(*) at the same time, resulting
757
// both in 0 rec's then they will both insert a metamodel. The first metamodel that is
758
// stored will be lost in this scenario.
759
// This is not very likely to happen (only in the case of an empty repository)
760
// so we take our chances..
761
if (recsHit == 0)
762         {
763           stmt = session.getInternalSqlStatement("select count(*) as cnt from " + MODEL_TABLE);
764           ResultSet JavaDoc rs = stmt.executeQuery();
765           if (rs.next())
766           {
767             if (rs.getInt("cnt") != 0) lockFailed = true;
768           }
769           rs.close();
770           stmt.close();
771           // empty repository?
772
if (!lockFailed)
773           {
774             // insert an empty model with a lock:
775
_modelLockTag = lockString;
776             storeModelXml(EMPTY_MODEL_XML_DOC);
777           }
778         }
779
780         if (!lockFailed)
781         {
782           // Lock was ok; check to see if we locked the original model. If not
783
// fail because someone else updated it in the mean time.
784
stmt = session.getInternalSqlStatement("select metamodel from " + MODEL_TABLE);
785           ResultSet JavaDoc rs = stmt.executeQuery();
786           String JavaDoc modelInDB = EMPTY_MODEL_XML_DOC;
787           if (rs.next())
788           {
789             modelInDB = new String JavaDoc(SqlStatement.getBlob(rs, "metamodel"));
790           }
791           rs.close();
792           stmt.close();
793           if (!modelInDB.equals(getOriginalModel()))
794           {
795             lockFailed = true;
796             session.rollback();
797             msg = Messages.getString("RdbmsPersistenceManager.ModelUpdated");
798           }
799           else _modelLockTag = lockString;
800         }
801         session.commit();
802       }
803       finally
804       {
805         session.close();
806       }
807     }
808     catch (Exception JavaDoc x)
809     {
810       throw new CatalogException(x);
811     }
812     if (lockFailed)
813     {
814       if (shouldTrace(TRACE_INTERNAL)) trace("Lock failed");
815       if (msg == null) msg = Messages.getString("RdbmsPersistenceManager.locked", getCurrentLockTag());
816       throw new CatalogException(Messages.getString("RdbmsPersistenceManager.CouldNotLockModel", msg));
817     }
818     else if (shouldTrace(TRACE_INTERNAL)) trace("Model lock aquired");
819
820   }
821
822   /**
823    * Description of the Method
824    *
825    * @exception CatalogException
826    * Description of the Exception
827    */

828   public void unlockModel() throws CatalogException
829   {
830     try
831     {
832       if (_modelLockTag == null) throw new CatalogException(Messages.getString("RdbmsPersistenceManager.NoLockAquired"));
833       RdbmsSession session = (RdbmsSession) createSession();
834       try
835       {
836         SqlStatement stmt = session.getInternalSqlStatement("update " + MODEL_TABLE + " set locked_by = null "
837                                                             + " where (locked_by is null or locked_by = :lockedBy)");
838
839         stmt.setString("lockedBy", _modelLockTag);
840         int recsHit = stmt.executeUpdate();
841         stmt.close();
842         session.commit();
843         _modelLockTag = null;
844         if (shouldTrace(TRACE_INTERNAL)) trace("Model unlocked");
845         if (recsHit == 0) throw new CatalogException(Messages.getString("RdbmsPersistenceManager.LockInvalidated"));
846       }
847       finally
848       {
849         session.close();
850       }
851     }
852     catch (Exception JavaDoc x)
853     {
854       throw new CatalogException(x);
855     }
856   }
857
858   /**
859    * Description of the Method
860    *
861    * @exception CatalogException
862    * Description of the Exception
863    */

864   public void forceUnlockModel() throws CatalogException
865   {
866     try
867     {
868       RdbmsSession session = (RdbmsSession) createSession();
869       try
870       {
871         SqlStatement stmt = session.getInternalSqlStatement("update " + MODEL_TABLE + " set locked_by = null ");
872
873         stmt.executeUpdate();
874         stmt.close();
875         session.commit();
876       }
877       finally
878       {
879         session.close();
880       }
881     }
882     catch (Exception JavaDoc x)
883     {
884       throw new CatalogException(x);
885     }
886   }
887
888   /**
889    * Sets the estimatedConcurrentSessions of the RdbmsPersistenceManager object
890    *
891    * @param estimate
892    * The new estimatedConcurrentSessions value
893    */

894   public void setEstimatedConcurrentSessions(int estimate)
895   {
896     _maxConnectionPoolSize = estimate;
897   }
898 }
Popular Tags