Main Page | Packages | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

DatabasesParser.java

00001 /**
00002  * C-JDBC: Clustered JDBC.
00003  * Copyright (C) 2002-2005 French National Institute For Research In Computer
00004  * Science And Control (INRIA).
00005  * Contact: c-jdbc@objectweb.org
00006  * 
00007  * This library is free software; you can redistribute it and/or modify it
00008  * under the terms of the GNU Lesser General Public License as published by the
00009  * Free Software Foundation; either version 2.1 of the License, or any later
00010  * version.
00011  * 
00012  * This library is distributed in the hope that it will be useful, but WITHOUT
00013  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
00015  * for more details.
00016  * 
00017  * You should have received a copy of the GNU Lesser General Public License
00018  * along with this library; if not, write to the Free Software Foundation,
00019  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00020  *
00021  * Initial developer(s): Emmanuel Cecchet.
00022  * Contributor(s): Mathieu Peltier, Sara Bouchenakm Nicolas Modrzyk
00023  */
00024 
00025 package org.objectweb.cjdbc.controller.xml;
00026 
00027 import java.io.IOException;
00028 import java.io.InputStream;
00029 import java.io.StringReader;
00030 import java.util.ArrayList;
00031 import java.util.Hashtable;
00032 
00033 import javax.management.NotCompliantMBeanException;
00034 import javax.management.ObjectName;
00035 
00036 import org.apache.regexp.RESyntaxException;
00037 import org.objectweb.cjdbc.common.exceptions.ControllerException;
00038 import org.objectweb.cjdbc.common.exceptions.ExceptionTypes;
00039 import org.objectweb.cjdbc.common.i18n.Translate;
00040 import org.objectweb.cjdbc.common.jmx.JmxConstants;
00041 import org.objectweb.cjdbc.common.log.Trace;
00042 import org.objectweb.cjdbc.common.sql.filters.AbstractBlobFilter;
00043 import org.objectweb.cjdbc.common.sql.filters.MacrosHandler;
00044 import org.objectweb.cjdbc.common.sql.schema.DatabaseColumn;
00045 import org.objectweb.cjdbc.common.sql.schema.DatabaseProcedure;
00046 import org.objectweb.cjdbc.common.sql.schema.DatabaseProcedureParameter;
00047 import org.objectweb.cjdbc.common.sql.schema.DatabaseSchema;
00048 import org.objectweb.cjdbc.common.sql.schema.DatabaseTable;
00049 import org.objectweb.cjdbc.common.users.AdminUser;
00050 import org.objectweb.cjdbc.common.users.DatabaseBackendUser;
00051 import org.objectweb.cjdbc.common.users.VirtualDatabaseUser;
00052 import org.objectweb.cjdbc.common.util.Constants;
00053 import org.objectweb.cjdbc.common.xml.DatabasesXmlTags;
00054 import org.objectweb.cjdbc.common.xml.XmlValidator;
00055 import org.objectweb.cjdbc.controller.authentication.AuthenticationManager;
00056 import org.objectweb.cjdbc.controller.authentication.AuthenticationManagerException;
00057 import org.objectweb.cjdbc.controller.backend.BackendRecoveryPolicy;
00058 import org.objectweb.cjdbc.controller.backend.DatabaseBackend;
00059 import org.objectweb.cjdbc.controller.backend.DatabaseBackendSchemaConstants;
00060 import org.objectweb.cjdbc.controller.backend.rewriting.AbstractRewritingRule;
00061 import org.objectweb.cjdbc.controller.backend.rewriting.PatternRewritingRule;
00062 import org.objectweb.cjdbc.controller.backend.rewriting.ReplaceAllRewritingRule;
00063 import org.objectweb.cjdbc.controller.backend.rewriting.SimpleRewritingRule;
00064 import org.objectweb.cjdbc.controller.backup.BackupManager;
00065 import org.objectweb.cjdbc.controller.cache.metadata.MetadataCache;
00066 import org.objectweb.cjdbc.controller.cache.parsing.ParsingCache;
00067 import org.objectweb.cjdbc.controller.cache.result.AbstractResultCache;
00068 import org.objectweb.cjdbc.controller.cache.result.CachingGranularities;
00069 import org.objectweb.cjdbc.controller.cache.result.ResultCacheFactory;
00070 import org.objectweb.cjdbc.controller.cache.result.ResultCacheRule;
00071 import org.objectweb.cjdbc.controller.cache.result.rules.EagerCaching;
00072 import org.objectweb.cjdbc.controller.connection.FailFastPoolConnectionManager;
00073 import org.objectweb.cjdbc.controller.connection.RandomWaitPoolConnectionManager;
00074 import org.objectweb.cjdbc.controller.connection.SimpleConnectionManager;
00075 import org.objectweb.cjdbc.controller.connection.VariablePoolConnectionManager;
00076 import org.objectweb.cjdbc.controller.core.Controller;
00077 import org.objectweb.cjdbc.controller.jmx.MBeanServerManager;
00078 import org.objectweb.cjdbc.controller.loadbalancer.AbstractLoadBalancer;
00079 import org.objectweb.cjdbc.controller.loadbalancer.paralleldb.ParallelDB;
00080 import org.objectweb.cjdbc.controller.loadbalancer.paralleldb.ParallelDB_LPRF;
00081 import org.objectweb.cjdbc.controller.loadbalancer.paralleldb.ParallelDB_RR;
00082 import org.objectweb.cjdbc.controller.loadbalancer.policies.WaitForCompletionPolicy;
00083 import org.objectweb.cjdbc.controller.loadbalancer.policies.createtable.CreateTableAll;
00084 import org.objectweb.cjdbc.controller.loadbalancer.policies.createtable.CreateTablePolicy;
00085 import org.objectweb.cjdbc.controller.loadbalancer.policies.createtable.CreateTableRandom;
00086 import org.objectweb.cjdbc.controller.loadbalancer.policies.createtable.CreateTableRoundRobin;
00087 import org.objectweb.cjdbc.controller.loadbalancer.policies.createtable.CreateTableRule;
00088 import org.objectweb.cjdbc.controller.loadbalancer.policies.errorchecking.ErrorCheckingAll;
00089 import org.objectweb.cjdbc.controller.loadbalancer.policies.errorchecking.ErrorCheckingPolicy;
00090 import org.objectweb.cjdbc.controller.loadbalancer.policies.errorchecking.ErrorCheckingRandom;
00091 import org.objectweb.cjdbc.controller.loadbalancer.policies.errorchecking.ErrorCheckingRoundRobin;
00092 import org.objectweb.cjdbc.controller.loadbalancer.raidb0.RAIDb0;
00093 import org.objectweb.cjdbc.controller.loadbalancer.raidb1.RAIDb1_LPRF;
00094 import org.objectweb.cjdbc.controller.loadbalancer.raidb1.RAIDb1_RR;
00095 import org.objectweb.cjdbc.controller.loadbalancer.raidb1.RAIDb1_WRR;
00096 import org.objectweb.cjdbc.controller.loadbalancer.raidb1.RAIDb1ec_RR;
00097 import org.objectweb.cjdbc.controller.loadbalancer.raidb1.RAIDb1ec_WRR;
00098 import org.objectweb.cjdbc.controller.loadbalancer.raidb2.RAIDb2_LPRF;
00099 import org.objectweb.cjdbc.controller.loadbalancer.raidb2.RAIDb2_RR;
00100 import org.objectweb.cjdbc.controller.loadbalancer.raidb2.RAIDb2_WRR;
00101 import org.objectweb.cjdbc.controller.loadbalancer.raidb2.RAIDb2ec_RR;
00102 import org.objectweb.cjdbc.controller.loadbalancer.raidb2.RAIDb2ec_WRR;
00103 import org.objectweb.cjdbc.controller.loadbalancer.singledb.SingleDB;
00104 import org.objectweb.cjdbc.controller.monitoring.SQLMonitoring;
00105 import org.objectweb.cjdbc.controller.monitoring.SQLMonitoringRule;
00106 import org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog;
00107 import org.objectweb.cjdbc.controller.requestmanager.RAIDbLevels;
00108 import org.objectweb.cjdbc.controller.requestmanager.RequestManager;
00109 import org.objectweb.cjdbc.controller.requestmanager.distributed.RAIDb1DistributedRequestManager;
00110 import org.objectweb.cjdbc.controller.requestmanager.distributed.RAIDb2DistributedRequestManager;
00111 import org.objectweb.cjdbc.controller.scheduler.AbstractScheduler;
00112 import org.objectweb.cjdbc.controller.scheduler.raidb0.RAIDb0PassThroughLevelScheduler;
00113 import org.objectweb.cjdbc.controller.scheduler.raidb0.RAIDb0PessimisticTransactionLevelScheduler;
00114 import org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1OptimisticQueryLevelScheduler;
00115 import org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1OptimisticTransactionLevelScheduler;
00116 import org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1PassThroughScheduler;
00117 import org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1PessimisticTransactionLevelScheduler;
00118 import org.objectweb.cjdbc.controller.scheduler.raidb1.RAIDb1QueryLevelScheduler;
00119 import org.objectweb.cjdbc.controller.scheduler.raidb2.RAIDb2PassThroughLevelScheduler;
00120 import org.objectweb.cjdbc.controller.scheduler.raidb2.RAIDb2PessimisticTransactionLevelScheduler;
00121 import org.objectweb.cjdbc.controller.scheduler.raidb2.RAIDb2QueryLevelScheduler;
00122 import org.objectweb.cjdbc.controller.scheduler.singledb.SingleDBPassThroughScheduler;
00123 import org.objectweb.cjdbc.controller.scheduler.singledb.SingleDBPessimisticTransactionLevelScheduler;
00124 import org.objectweb.cjdbc.controller.virtualdatabase.DistributedVirtualDatabase;
00125 import org.objectweb.cjdbc.controller.virtualdatabase.VirtualDatabase;
00126 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.CJDBCGroupMessage;
00127 import org.xml.sax.Attributes;
00128 import org.xml.sax.InputSource;
00129 import org.xml.sax.SAXException;
00130 import org.xml.sax.SAXParseException;
00131 import org.xml.sax.XMLReader;
00132 import org.xml.sax.helpers.DefaultHandler;
00133 import org.xml.sax.helpers.XMLReaderFactory;
00134 
00135 /**
00136  * Parses an XML content conforming to C-JDBC.dtd and configure the given C-JDBC
00137  * Controller accordingly.
00138  * 
00139  * @author <a href="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
00140  * @author <a href="mailto:Mathieu.Peltier@inrialpes.fr">Mathieu Peltier </a>
00141  * @author <a href="mailto:Nicolas.Modrzyk@inrialpes.fr">Nicolas Modrzyk </a>
00142  * @version 1.0
00143  */
00144 public class DatabasesParser extends DefaultHandler
00145 {
00146 
00147   /** XML parser. */
00148   private XMLReader               parser;
00149 
00150   /** Logger instance. */
00151   static Trace                    logger                 = Trace
00152                                                              .getLogger(DatabasesParser.class
00153                                                                  .getName());
00154 
00155   /** C-JDBC controller to setup. */
00156   private Controller              controller;
00157 
00158   /** dbToPrepare is used if only a specified database has to be loaded */
00159   private Hashtable               dbToPrepare            = null;
00160   /** setter for jumping from one VirtualDatabase definition to the next one */
00161   private boolean                 skipDatabase           = false;
00162 
00163   /**
00164    * Parsing of Users are only defined in Admin at the moment, but may be
00165    * defined somewhere else in the future.
00166    */
00167   private boolean                 parsingAdminUsers      = false;
00168 
00169   private VirtualDatabase         currentVirtualDatabase = null;
00170   private BackupManager           currentBackupManager   = null;
00171   private DatabaseBackend         currentBackend;
00172   private DatabaseBackendUser     currentDatabaseBackendUser;
00173   private AuthenticationManager   currentAuthenticationManager;
00174   private AbstractScheduler       currentRequestScheduler;
00175   private AbstractResultCache     currentResultCache;
00176   private MetadataCache           currentMetadataCache   = null;
00177   private ParsingCache            currentParsingCache    = null;
00178   private ResultCacheRule         currentResultCacheRule;
00179   private MacrosHandler           currentMacroHandler;
00180   private AbstractLoadBalancer    currentLoadBalancer;
00181   private JDBCRecoveryLog         currentRecoveryLog;
00182   private VirtualDatabaseUser     currentVirtualUser;
00183   private DatabaseSchema          currentDatabaseSchema;
00184   private DatabaseTable           currentTable;
00185   private DatabaseProcedure       currentProcedure;
00186   private int                     numberOfColumns;
00187 
00188   private String                  connectionManagerVLogin;
00189   private WaitForCompletionPolicy currentWaitForCompletionPolicy;
00190 
00191   private long                    beginTimeout;
00192   private long                    commitTimeout;
00193   private long                    rollbackTimeout;
00194   private int                     requestTimeout;
00195 
00196   private boolean                 caseSensitiveParsing;
00197 
00198   private CreateTablePolicy       currentCreateTablePolicy;
00199   private CreateTableRule         currentCreateTableRule;
00200   private ArrayList               backendNameList;
00201   private ErrorCheckingPolicy     currentErrorCheckingPolicy;
00202 
00203   private int                     currentNbOfConcurrentReads;
00204 
00205   private BackendRecoveryPolicy   currentBackendRecoveryPolicy;
00206 
00207   /**
00208    * Creates a new <code>DatabasesParser</code> instance. This method
00209    * Instanciates also a new <code>DatabasesParser</code>.
00210    * 
00211    * @param controller <code>Controller</code> to load the Virtual Database
00212    *          into
00213    * @throws SAXException if an error occurs
00214    */
00215   public DatabasesParser(Controller controller) throws SAXException
00216   {
00217     prepareHandler(controller);
00218   }
00219 
00220   /**
00221    * Creates a new <code>DatabasesParser</code> instance. This method
00222    * Instanciates also a new <code>DatabasesParser</code>. This instance will
00223    * look only for the specified database.
00224    * 
00225    * @param controller <code>Controller</code> to load the Virtual Database
00226    *          into
00227    * @param virtualName the specified <code>VirtualDatabase</code> to load.
00228    * @param autoLoad autoenable switch
00229    * @param checkPoint checkpoint information
00230    * @throws SAXException if an error occurs
00231    */
00232   public DatabasesParser(Controller controller, String virtualName,
00233       int autoLoad, String checkPoint) throws SAXException
00234   {
00235     prepareHandler(controller);
00236     // Test if a name has been specified. Otherwise skip.
00237     if (virtualName != null)
00238       prepareDB(virtualName, autoLoad, checkPoint);
00239   }
00240 
00241   private void prepareHandler(Controller controller) throws SAXException
00242   {
00243     // Instantiate a new parser
00244     parser = XMLReaderFactory.createXMLReader();
00245 
00246     this.controller = controller;
00247 
00248     // Activate validation
00249     parser.setFeature("http://xml.org/sax/features/validation", true);
00250 
00251     // Install error handler
00252     parser.setErrorHandler(this);
00253 
00254     // Install document handler
00255     parser.setContentHandler(this);
00256 
00257     // Install local entity resolver
00258     parser.setEntityResolver(this);
00259   }
00260 
00261   /**
00262    * Parses an XML content according to C-JDBC DTD.
00263    * 
00264    * @param xml a <code>String</code> containing the XML content to parse
00265    * @exception SAXException if an error occurs
00266    * @exception IOException if an error occurs
00267    */
00268   public void readXML(String xml) throws IOException, SAXException
00269   {
00270     InputSource input = new InputSource(new StringReader(xml));
00271     parser.parse(input);
00272   }
00273 
00274   /**
00275    * Validate an XML content according to C-JDBC DTD.
00276    * 
00277    * @param xml content
00278    * @param validateBeforeParsing if true validate the document before the
00279    *          parsing
00280    * @throws IOException if an error occurs
00281    * @throws SAXException if an error occurs
00282    */
00283   public void readXML(String xml, boolean validateBeforeParsing)
00284       throws IOException, SAXException
00285   {
00286     if (validateBeforeParsing)
00287     {
00288       XmlValidator validator = new XmlValidator(Constants.C_JDBC_DTD_FILE, xml);
00289       if (logger.isDebugEnabled())
00290       {
00291         if (validator.isDtdValid())
00292           logger.debug(Translate.get("virtualdatabase.xml.dtd.validated"));
00293         if (validator.isXmlValid())
00294           logger.debug(Translate.get("virtualdatabase.xml.document.validated"));
00295       }
00296 
00297       if (validator.getWarnings().size() > 0)
00298       {
00299         ArrayList warnings = validator.getWarnings();
00300         for (int i = 0; i < warnings.size(); i++)
00301           logger.warn(Translate.get("virtualdatabase.xml.parsing.warning",
00302               warnings.get(i)));
00303       }
00304 
00305       if (!validator.isDtdValid())
00306         logger.error(Translate.get("virtualdatabase.xml.dtd.not.validated"));
00307       if (!validator.isXmlValid())
00308         logger.error(Translate
00309             .get("virtualdatabase.xml.document.not.validated"));
00310 
00311       ArrayList errors = validator.getExceptions();
00312       for (int i = 0; i < errors.size(); i++)
00313         logger.error(((Exception) errors.get(i)).getMessage());
00314 
00315       if (!validator.isValid())
00316         throw new SAXException(ExceptionTypes.XML_DOCUMENT_INVALID);
00317     }
00318     this.readXML(xml);
00319   }
00320 
00321   /**
00322    * Handles notification of a non-recoverable parser error.
00323    * 
00324    * @param e the warning information encoded as an exception.
00325    * @exception SAXException any SAX exception, possibly wrapping another
00326    *              exception.
00327    */
00328   public void fatalError(SAXParseException e) throws SAXException
00329   {
00330     logger.error(Translate.get("virtualdatabase.xml.parsing.fatal",
00331         new String[]{e.getPublicId(), String.valueOf(e.getLineNumber()),
00332             String.valueOf(e.getColumnNumber()), e.getMessage()}));
00333     throw e;
00334   }
00335 
00336   /**
00337    * Handles notification of a recoverable parser error.
00338    * 
00339    * @param e the warning information encoded as an exception.
00340    * @exception SAXException any SAX exception, possibly wrapping another
00341    *              exception
00342    */
00343   public void error(SAXParseException e) throws SAXException
00344   {
00345     logger.error(Translate.get("virtualdatabase.xml.parsing.error",
00346         new String[]{e.getPublicId(), String.valueOf(e.getLineNumber()),
00347             String.valueOf(e.getColumnNumber()), e.getMessage()}));
00348     throw e;
00349   }
00350 
00351   /**
00352    * Allows to parse the document with a local copy of the DTD whatever the
00353    * original <code>DOCTYPE</code> found. Warning, this method is called only
00354    * if the XML document contains a <code>DOCTYPE</code>.
00355    * 
00356    * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String,
00357    *      java.lang.String)
00358    */
00359   public InputSource resolveEntity(String publicId, String systemId)
00360       throws SAXException
00361   {
00362     InputStream stream = DatabasesXmlTags.class.getResourceAsStream("/"
00363         + Constants.C_JDBC_DTD_FILE);
00364     if (stream == null)
00365       throw new SAXException("Cannot find C-JDBC DTD file '"
00366           + Constants.C_JDBC_DTD_FILE + "' in classpath");
00367 
00368     return new InputSource(stream);
00369   }
00370 
00371   /**
00372    * If this method is called. Only the specified DB of the Xml file will be
00373    * loaded.
00374    * 
00375    * @param virtualName <code>VirtualDatabase</code> name
00376    * @param autoLoad autoenable switch
00377    * @param checkPoint checkpoint for recovery
00378    */
00379   public void prepareDB(String virtualName, int autoLoad, String checkPoint)
00380   {
00381     dbToPrepare = new Hashtable(3);
00382     dbToPrepare.put("virtualName", virtualName);
00383     dbToPrepare.put("autoEnable", String.valueOf(autoLoad));
00384     dbToPrepare.put("checkPoint", checkPoint);
00385   }
00386 
00387   /**
00388    * Initializes parsing of a document.
00389    * 
00390    * @exception SAXException unspecialized error
00391    */
00392   public void startDocument() throws SAXException
00393   {
00394     logger.info(Translate.get("virtualdatabase.xml.start"));
00395   }
00396 
00397   /**
00398    * Finalizes parsing of a document.
00399    * 
00400    * @exception SAXException unspecialized error
00401    */
00402   public void endDocument() throws SAXException
00403   {
00404     logger.info(Translate.get("virtualdatabase.xml.done"));
00405   }
00406 
00407   /**
00408    * Analyzes an element first line.
00409    * 
00410    * @param uri name space URI
00411    * @param localName local name
00412    * @param name element raw name
00413    * @param atts element attributes
00414    * @exception SAXException if an error occurs
00415    */
00416   public void startElement(String uri, String localName, String name,
00417       Attributes atts) throws SAXException
00418   {
00419     logger.debug(Translate.get("virtualdatabase.xml.parsing.start", name));
00420 
00421     // Virtual database
00422     if (name.equals(DatabasesXmlTags.ELT_VirtualDatabase))
00423     {
00424       if (dbToPrepare == null)
00425       {
00426         // Prepare all databases
00427         newVirtualDatabase(atts);
00428       }
00429       else
00430       {
00431         // Only prepare one database
00432         String virtualName = atts.getValue(DatabasesXmlTags.ATT_name);
00433         if (virtualName.equalsIgnoreCase((String) dbToPrepare
00434             .get("virtualName")))
00435         {
00436           // This is the database that we want to prepare
00437           skipDatabase = false;
00438           newVirtualDatabase(atts);
00439         }
00440         else
00441         {
00442           // Skip to next one
00443           skipDatabase = true;
00444         }
00445       }
00446     }
00447     // Skip to next definition of a virtualDatabase ?
00448     if (skipDatabase)
00449       return;
00450 
00451     // Distribution
00452     else if (name.equals(DatabasesXmlTags.ELT_Distribution))
00453       newDistribution(atts);
00454     else if (name.equals(DatabasesXmlTags.ELT_BackendRecoveryPolicy))
00455       newBackendRecoveryPolicy(atts);
00456     else if (name.equals(DatabasesXmlTags.ELT_ControllerName))
00457       newControllerName(atts);
00458 
00459     // Monitoring
00460     else if (name.equals(DatabasesXmlTags.ELT_SQLMonitoring))
00461       newSQLMonitoring(atts);
00462     else if (name.equals(DatabasesXmlTags.ELT_SQLMonitoringRule))
00463       newSQLMonitoringRule(atts);
00464 
00465     // Backup
00466     else if (name.equals(DatabasesXmlTags.ELT_Backup))
00467       newBackupManager(atts);
00468 
00469     // Database backend
00470     else if (name.equals(DatabasesXmlTags.ELT_DatabaseBackend))
00471       newDatabaseBackend(atts);
00472     else if (name.equals(DatabasesXmlTags.ELT_RewritingRule))
00473       newRewritingRule(atts);
00474 
00475     // Authentication manager
00476     else if (name.equals(DatabasesXmlTags.ELT_AuthenticationManager))
00477       newAuthenticationManager(atts);
00478     else if (name.equals(DatabasesXmlTags.ELT_Admin))
00479       parsingAdminUsers = true;
00480     else if (name.equals(DatabasesXmlTags.ELT_User) && parsingAdminUsers)
00481       newAdminUser(atts);
00482     else if (name.equals(DatabasesXmlTags.ELT_VirtualLogin))
00483       newVirtualLogin(atts);
00484 
00485     // Request manager
00486     else if (name.equals(DatabasesXmlTags.ELT_RequestManager))
00487       newRequestManager(atts);
00488 
00489     // Macro Handler
00490     else if (name.equals(DatabasesXmlTags.ELT_MacroHandling))
00491       newMacroHandler(atts);
00492 
00493     // Request schedulers
00494     else if (name.equals(DatabasesXmlTags.ELT_SingleDBScheduler))
00495       newSingleDBScheduler(atts);
00496     else if (name.equals(DatabasesXmlTags.ELT_RAIDb0Scheduler))
00497       newRAIDb0Scheduler(atts);
00498     else if (name.equals(DatabasesXmlTags.ELT_RAIDb1Scheduler))
00499       newRAIDb1Scheduler(atts);
00500     else if (name.equals(DatabasesXmlTags.ELT_RAIDb2Scheduler))
00501       newRAIDb2Scheduler(atts);
00502 
00503     // Request caches
00504     else if (name.equals(DatabasesXmlTags.ELT_MetadataCache))
00505       newMetadataCache(atts);
00506     else if (name.equals(DatabasesXmlTags.ELT_ParsingCache))
00507       newParsingCache(atts);
00508     else if (name.equals(DatabasesXmlTags.ELT_ResultCache))
00509       newResultCache(atts);
00510     else if (name.equals(DatabasesXmlTags.ELT_DefaultResultCacheRule))
00511       newDefaultResultCacheRule(atts);
00512     else if (name.equals(DatabasesXmlTags.ELT_ResultCacheRule))
00513       newResultCacheRule(atts);
00514     else if (name.equals(DatabasesXmlTags.ELT_NoCaching))
00515       currentResultCacheRule.setCacheBehavior(ResultCacheFactory
00516           .getCacheBehaviorInstance(DatabasesXmlTags.ELT_NoCaching, null));
00517     else if (name.equals(DatabasesXmlTags.ELT_EagerCaching))
00518       newEagerCaching(atts);
00519     else if (name.equals(DatabasesXmlTags.ELT_RelaxedCaching))
00520       newRelaxedCaching(atts);
00521 
00522     // Request load balancers
00523     else if (name.equals(DatabasesXmlTags.ELT_SingleDB))
00524       newSingleDBRequestLoadBalancer(atts);
00525     else if (name.equals(DatabasesXmlTags.ELT_ParallelDB_RoundRobin))
00526       newParallelDBRoundRobinLoadBalancer(atts);
00527     else if (name
00528         .equals(DatabasesXmlTags.ELT_ParallelDB_LeastPendingRequestsFirst))
00529       newParallelDBLeastPendingRequestsFirst(atts);
00530     else if (name.equals(DatabasesXmlTags.ELT_RAIDb_0))
00531       newRAIDb0LoadBalancer(atts);
00532     else if (name.equals(DatabasesXmlTags.ELT_RAIDb_1))
00533       newRAIDb1LoadBalancer(atts);
00534     else if (name.equals(DatabasesXmlTags.ELT_RAIDb_1_RoundRobin))
00535       newRAIDb1RoundRobinLoadBalancer(atts);
00536     else if (name.equals(DatabasesXmlTags.ELT_RAIDb_1_WeightedRoundRobin))
00537       newRAIDb1WeightedRoundRobinLoadBalancer(atts);
00538     else if (name
00539         .equals(DatabasesXmlTags.ELT_RAIDb_1_LeastPendingRequestsFirst))
00540       newRAIDb1LeastPendingRequestsFirst(atts);
00541     else if (name.equals(DatabasesXmlTags.ELT_RAIDb_1ec))
00542       newRAIDb1ecLoadBalancer(atts);
00543     else if (name.equals(DatabasesXmlTags.ELT_RAIDb_1ec_RoundRobin))
00544       newRAIDb1ecRoundRobinLoadBalancer(atts);
00545     else if (name.equals(DatabasesXmlTags.ELT_RAIDb_1ec_WeightedRoundRobin))
00546       newRAIDb1ecWeightedRoundRobinLoadBalancer(atts);
00547     else if (name.equals(DatabasesXmlTags.ELT_RAIDb_2))
00548       newRAIDb2LoadBalancer(atts);
00549     else if (name.equals(DatabasesXmlTags.ELT_RAIDb_2_RoundRobin))
00550       newRAIDb2RoundRobinLoadBalancer(atts);
00551     else if (name.equals(DatabasesXmlTags.ELT_RAIDb_2_WeightedRoundRobin))
00552       newRAIDb2WeightedRoundRobinLoadBalancer(atts);
00553     else if (name
00554         .equals(DatabasesXmlTags.ELT_RAIDb_2_LeastPendingRequestsFirst))
00555       newRAIDb2LeastPendingRequestsFirst(atts);
00556     else if (name.equals(DatabasesXmlTags.ELT_RAIDb_2ec))
00557       newRAIDb2ecLoadBalancer(atts);
00558     else if (name.equals(DatabasesXmlTags.ELT_RAIDb_2ec_RoundRobin))
00559       newRAIDb2ecRoundRobinLoadBalancer(atts);
00560     else if (name.equals(DatabasesXmlTags.ELT_RAIDb_2ec_WeightedRoundRobin))
00561       newRAIDb2ecWeightedRoundRobinLoadBalancer(atts);
00562 
00563     // Policies
00564     else if (name.equals(DatabasesXmlTags.ELT_WaitForCompletion))
00565       newWaitForCompletion(atts);
00566     else if (name.equals(DatabasesXmlTags.ELT_ErrorChecking))
00567       newErrorChecking(atts);
00568     else if (name.equals(DatabasesXmlTags.ELT_CreateTable))
00569       newCreateTable(atts);
00570     else if (name.equals(DatabasesXmlTags.ELT_BackendName))
00571       newBackendName(atts);
00572     else if (name.equals(DatabasesXmlTags.ELT_BackendWeight))
00573       newBackendWeight(atts);
00574 
00575     // Recovery log
00576     else if (name.equals(DatabasesXmlTags.ELT_FileRecoveryLog))
00577       newFileRecoveryLog(atts);
00578     else if (name.equals(DatabasesXmlTags.ELT_JDBCRecoveryLog))
00579       newJDBCRecoveryLog(atts);
00580     else if (name.equals(DatabasesXmlTags.ELT_RecoveryLogTable))
00581       newJDBCRecoveryLogTable(atts);
00582     else if (name.equals(DatabasesXmlTags.ELT_CheckpointTable))
00583       newJDBCRecoveryCheckpointTable(atts);
00584     else if (name.equals(DatabasesXmlTags.ELT_BackendTable))
00585       newJDBCRecoveryBackendTable(atts);
00586 
00587     // Connection managers
00588     else if (name.equals(DatabasesXmlTags.ELT_ConnectionManager))
00589       newConnectionManager(atts);
00590     else if (name.equals(DatabasesXmlTags.ELT_SimpleConnectionManager))
00591       newSimpleConnectionManager(atts);
00592     else if (name.equals(DatabasesXmlTags.ELT_FailFastPoolConnectionManager))
00593       newFailFastPoolConnectionManager(atts);
00594     else if (name.equals(DatabasesXmlTags.ELT_RandomWaitPoolConnectionManager))
00595       newRandomWaitPoolConnectionManager(atts);
00596     else if (name.equals(DatabasesXmlTags.ELT_VariablePoolConnectionManager))
00597       newVariablePoolConnectionManager(atts);
00598 
00599     // Database schema
00600     else if (name.equals(DatabasesXmlTags.ELT_DatabaseSchema))
00601       newDatabaseSchema(atts);
00602     else if (name.equals(DatabasesXmlTags.ELT_DatabaseStaticSchema))
00603     {
00604       if (currentBackend.getDynamicPrecision() != DatabaseBackendSchemaConstants.DynamicPrecisionStatic)
00605       {
00606         String msg = Translate.get(
00607             "virtualdatabase.xml.schema.static.incompatible.dynamic",
00608             currentBackend.getName());
00609         logger.error(msg);
00610         throw new SAXException(msg);
00611       }
00612       currentDatabaseSchema = new DatabaseSchema();
00613     }
00614 
00615     // Database table (inside a DatabaseSchema)
00616     else if (name.equals(DatabasesXmlTags.ELT_DatabaseTable))
00617       newDatabaseTable(atts);
00618 
00619     // Table column (inside a DatabaseSchema/DatabaseTable)
00620     else if (name.equals(DatabasesXmlTags.ELT_DatabaseColumn))
00621       newDatabaseColumn(atts);
00622 
00623     else if (name.equals(DatabasesXmlTags.ELT_DatabaseProcedure))
00624       newDatabaseProcedure(atts);
00625     else if (name.equals(DatabasesXmlTags.ELT_DatabaseProcedureColumn))
00626       newDatabaseProcedureColumn(atts);
00627   }
00628 
00629   /**
00630    * DatabasesParser for end of element.
00631    * 
00632    * @param uri name space URI
00633    * @param localName local name
00634    * @param name element raw name
00635    * @exception SAXException if an error occurs
00636    */
00637   public void endElement(String uri, String localName, String name)
00638       throws SAXException
00639   {
00640     logger.debug(Translate.get("virtualdatabase.xml.parsing.end", name));
00641     // Test if skip is needed
00642     if (skipDatabase)
00643       return;
00644 
00645     // Virtual database
00646     if (name.equals(DatabasesXmlTags.ELT_VirtualDatabase))
00647     {
00648       if (logger.isDebugEnabled())
00649         logger.debug(Translate.get("virtualdatabase.xml.add.virtualdatabase"));
00650 
00651       if (currentVirtualDatabase != null)
00652       {
00653         try
00654         {
00655           if (currentVirtualDatabase instanceof DistributedVirtualDatabase)
00656             ((DistributedVirtualDatabase) currentVirtualDatabase).joinGroup();
00657           if (dbToPrepare == null)
00658           {
00659             controller.addVirtualDatabase(currentVirtualDatabase);
00660           }
00661           else
00662           {
00663             int autoLoad = Integer.parseInt((String) dbToPrepare
00664                 .get("autoEnable"));
00665             String checkPoint = (String) dbToPrepare.get("checkPoint");
00666             // checkPoint is store as "" in Hashtable
00667             // but methods to enable backend requires checkPoint to be null
00668             // if no recovery from checkpoint
00669             checkPoint = checkPoint.equalsIgnoreCase("") ? null : checkPoint;
00670             controller.addVirtualDatabase(currentVirtualDatabase, autoLoad,
00671                 checkPoint);
00672           }
00673         }
00674         catch (Exception e)
00675         {
00676           String msg = Translate
00677               .get("controller.add.virtualdatabase.failed", e);
00678           logger.error(msg, e);
00679         }
00680       }
00681       currentVirtualDatabase = null;
00682     }
00683 
00684     // Request manager
00685     else if (name.equals(DatabasesXmlTags.ELT_RequestManager))
00686     {
00687       if (logger.isDebugEnabled())
00688         logger.debug(Translate.get("virtualdatabase.xml.requestmanager.set"));
00689 
00690       if (currentVirtualDatabase != null)
00691       {
00692         RequestManager requestManager = null;
00693 
00694         // We consider that SingleDB and ParallelDB balancers don't need macros
00695         // handler
00696         if (currentLoadBalancer == null)
00697           throw new SAXException("virtualdatabase.xml.loadbalancer.not.set");
00698         if (!(currentLoadBalancer instanceof SingleDB || currentLoadBalancer instanceof ParallelDB))
00699         {
00700           // If no macros handling has been specified, create a default one
00701           // based one the dtd default values
00702           if (currentMacroHandler == null)
00703             currentMacroHandler = new MacrosHandler(MacrosHandler.RAND_FLOAT,
00704                 1000, MacrosHandler.DATE_TIMESTAMP, MacrosHandler.DATE_DATE,
00705                 MacrosHandler.DATE_TIME, MacrosHandler.DATE_TIMESTAMP,
00706                 MacrosHandler.DATE_TIMESTAMP);
00707           currentLoadBalancer.setMacroHandler(currentMacroHandler);
00708         }
00709 
00710         try
00711         {
00712           if (currentVirtualDatabase.isDistributed())
00713           {
00714             switch (currentLoadBalancer.getRAIDbLevel())
00715             {
00716               case RAIDbLevels.SingleDB :
00717                 String smsg = Translate.get(
00718                     "virtualdatabase.xml.no.single.distributed.requestmanager",
00719                     currentLoadBalancer.getRAIDbLevel());
00720                 logger.error(smsg);
00721                 throw new SAXException(smsg);
00722               case RAIDbLevels.RAIDb1 :
00723                 requestManager = new RAIDb1DistributedRequestManager(
00724                     (DistributedVirtualDatabase) currentVirtualDatabase,
00725                     currentRequestScheduler, currentResultCache,
00726                     currentLoadBalancer, currentRecoveryLog, beginTimeout,
00727                     commitTimeout, rollbackTimeout);
00728                 break;
00729               case RAIDbLevels.RAIDb2 :
00730                 requestManager = new RAIDb2DistributedRequestManager(
00731                     (DistributedVirtualDatabase) currentVirtualDatabase,
00732                     currentRequestScheduler, currentResultCache,
00733                     currentLoadBalancer, currentRecoveryLog, beginTimeout,
00734                     commitTimeout, rollbackTimeout);
00735                 break;
00736               default :
00737                 String msg = Translate.get(
00738                     "virtualdatabase.xml.no.distributed.requestmanager",
00739                     currentLoadBalancer.getRAIDbLevel());
00740                 logger.error(msg);
00741                 throw new SAXException(msg);
00742             }
00743           }
00744           else
00745             requestManager = new RequestManager(currentVirtualDatabase,
00746                 currentRequestScheduler, currentResultCache,
00747                 currentLoadBalancer, currentRecoveryLog, beginTimeout,
00748                 commitTimeout, rollbackTimeout);
00749 
00750           if (requestManager != null)
00751           {
00752             if (currentParsingCache != null)
00753               requestManager.setParsingCache(currentParsingCache);
00754             if (currentMetadataCache != null)
00755               requestManager.setMetadataCache(currentMetadataCache);
00756             requestManager.setCaseSensitiveParsing(caseSensitiveParsing);
00757           }
00758 
00759           currentVirtualDatabase.setRequestManager(requestManager);
00760           if (currentBackupManager == null)
00761             currentBackupManager = new BackupManager();
00762           requestManager.setBackupManager(currentBackupManager);
00763         }
00764         catch (Exception e)
00765         {
00766           String msg = Translate
00767               .get("virtualdatabase.xml.requestmanager.creation.failed");
00768           logger.error(msg, e);
00769           throw new SAXException(msg, e);
00770         }
00771       }
00772     }
00773 
00774     // Database backend
00775     else if (name.equals(DatabasesXmlTags.ELT_DatabaseBackend))
00776     {
00777       if (currentBackend != null)
00778       {
00779         try
00780         {
00781           currentVirtualDatabase.addBackend(currentBackend, false);
00782         }
00783         catch (Exception e)
00784         {
00785           String msg = Translate.get("virtualdatabase.xml.backend.add.failed");
00786           logger.error(msg, e);
00787           throw new SAXException(msg, e);
00788         }
00789       }
00790       currentBackend = null;
00791     }
00792 
00793     // Authentication manager
00794     else if (name.equals(DatabasesXmlTags.ELT_AuthenticationManager))
00795     {
00796       if (currentVirtualDatabase != null)
00797       {
00798         currentVirtualDatabase
00799             .setAuthenticationManager(currentAuthenticationManager);
00800       }
00801     }
00802 
00803     // Request cache
00804     else if (name.equals(DatabasesXmlTags.ELT_RequestCache))
00805     {
00806       if (currentResultCache != null)
00807       { // Set default result cache rule if missing
00808         if (currentResultCache.getDefaultRule() == null)
00809         {
00810           ResultCacheRule defaultRule = null;
00811           try
00812           {
00813             defaultRule = new ResultCacheRule("", false, false, 1000);
00814           }
00815           catch (RESyntaxException impossible)
00816           {
00817           }
00818           defaultRule.setCacheBehavior(new EagerCaching(0));
00819           currentResultCache.setDefaultRule(defaultRule);
00820         }
00821       }
00822     }
00823     else if (name.equals(DatabasesXmlTags.ELT_DefaultResultCacheRule))
00824     {
00825       currentResultCache.setDefaultRule(currentResultCacheRule);
00826     }
00827 
00828     // Database schema
00829     else if (name.equals(DatabasesXmlTags.ELT_DatabaseStaticSchema))
00830     {
00831       if (currentDatabaseSchema != null)
00832       {
00833         if (currentBackend != null)
00834         {
00835           try
00836           {
00837             currentBackend.setDatabaseSchema(currentDatabaseSchema, true);
00838           }
00839           catch (Exception e)
00840           {
00841             logger.error(Translate
00842                 .get("virtualdatabase.xml.backend.set.schema.failed"), e);
00843           }
00844         }
00845         else
00846         {
00847           try
00848           {
00849             currentVirtualDatabase.setDatabaseSchema(currentDatabaseSchema,
00850                 true);
00851           }
00852           catch (Exception e)
00853           {
00854             logger.error(Translate
00855                 .get("virtualdatabase.xml.virtualdatabase.set.schema.failed"),
00856                 e);
00857           }
00858         }
00859         currentDatabaseSchema = null;
00860       }
00861     }
00862 
00863     // Database table
00864     else if (name.equals(DatabasesXmlTags.ELT_DatabaseTable))
00865     {
00866       if (currentTable != null)
00867       {
00868         try
00869         {
00870           ArrayList cols = currentTable.getColumns();
00871           if (cols == null)
00872             logger.warn(Translate.get("virtualdatabase.xml.table.no.column",
00873                 currentTable.getName()));
00874           else if (cols.size() != numberOfColumns)
00875             logger.warn(Translate.get(
00876                 "virtualdatabase.xml.table.column.mismatch", new String[]{
00877                     String.valueOf(numberOfColumns), currentTable.getName(),
00878                     String.valueOf(cols.size())}));
00879 
00880           currentDatabaseSchema.addTable(currentTable);
00881           if (logger.isDebugEnabled())
00882             logger.debug(Translate.get("virtualdatabase.xml.table.add",
00883                 currentTable.getName()));
00884         }
00885         catch (Exception e)
00886         {
00887           logger
00888               .error(Translate.get("virtualdatabase.xml.table.add.failed"), e);
00889         }
00890         currentTable = null;
00891       }
00892     }
00893 
00894     else if (name.equals(DatabasesXmlTags.ELT_DatabaseProcedure))
00895     {
00896       if (currentProcedure != null)
00897       {
00898         try
00899         {
00900 
00901           currentDatabaseSchema.addProcedure(currentProcedure);
00902           if (logger.isDebugEnabled())
00903             logger.debug(Translate.get("virtualdatabase.xml.procedure.add",
00904                 currentProcedure.getName()));
00905         }
00906         catch (Exception e)
00907         {
00908           logger.error(Translate
00909               .get("virtualdatabase.xml.procedure.add.failed"), e);
00910         }
00911         currentProcedure = null;
00912       }
00913     }
00914 
00915     // CreateTable rule
00916     else if (name.equals(DatabasesXmlTags.ELT_CreateTable))
00917     {
00918       if (currentCreateTablePolicy != null)
00919       {
00920         if (logger.isDebugEnabled())
00921           logger.debug(Translate.get("virtualdatabase.xml.create.table.add",
00922               currentCreateTableRule.getInformation()));
00923         currentCreateTablePolicy.addRule(currentCreateTableRule);
00924       }
00925     }
00926 
00927     // RAIDb-0 load balancer
00928     else if (name.equals(DatabasesXmlTags.ELT_RAIDb_0))
00929     {
00930       if (logger.isDebugEnabled())
00931         logger.debug(Translate
00932             .get("virtualdatabase.xml.loadbalancer.raidb0.set"));
00933 
00934       if (currentCreateTablePolicy.getDefaultRule() == null)
00935       {
00936         if (logger.isDebugEnabled())
00937           logger.debug(Translate
00938               .get("virtualdatabase.xml.create.table.default"));
00939         CreateTableRule rule = new CreateTableRoundRobin();
00940         currentCreateTablePolicy.addRule(rule);
00941       }
00942       try
00943       {
00944         currentLoadBalancer = new RAIDb0(currentVirtualDatabase,
00945             currentCreateTablePolicy);
00946       }
00947       catch (Exception e)
00948       {
00949         String msg = Translate
00950             .get("virtualdatabase.xml.loadbalancer.raidb0.failed");
00951         logger.error(msg, e);
00952         throw new SAXException(msg, e);
00953       }
00954     }
00955 
00956     // JDBC Recovery Log
00957     else if (name.equals(DatabasesXmlTags.ELT_RecoveryLog))
00958     {
00959       if (logger.isDebugEnabled())
00960         logger.debug(Translate
00961             .get("virtualdatabase.xml.recoverylog.cheking.tables"));
00962       {
00963         try
00964         {
00965           currentRecoveryLog.checkRecoveryLogTables();
00966         }
00967         catch (Exception e)
00968         {
00969           String msg = Translate
00970               .get("virtualdatabase.xml.recoverylog.cheking.tables.failed");
00971           logger.error(msg, e);
00972           throw new SAXException(msg);
00973         }
00974         // Set the last transaction id of the scheduler from the recovery logs
00975         try
00976         {
00977           currentRequestScheduler.initializeTransactionId(currentRecoveryLog
00978               .getLastTransactionId() + 1);
00979         }
00980         catch (Exception e)
00981         {
00982           String msg = Translate
00983               .get("virtualdatabase.xml.scheduler.initialization.failed");
00984           logger.error(msg, e);
00985           throw new SAXException(msg);
00986         }
00987       }
00988     }
00989   }
00990 
00991   /* Virtual database */
00992 
00993   /**
00994    * Sets {@link #currentVirtualDatabase}as a new <code> VirtualDatabase
00995    * </code>
00996    * using the parsed attributes. An exception is thrown in particular if a
00997    * virtual database with the same name is already registered in the
00998    * controller.
00999    * 
01000    * @param atts parsed attributes
01001    * @exception SAXException if an error occurs
01002    */
01003   private void newVirtualDatabase(Attributes atts) throws SAXException
01004   {
01005     String name = atts.getValue(DatabasesXmlTags.ATT_name);
01006     String maxNbOfConnections = atts
01007         .getValue(DatabasesXmlTags.ATT_maxNbOfConnections);
01008     String poolThreads = atts.getValue(DatabasesXmlTags.ATT_poolThreads);
01009     String minNbOfThreads = atts.getValue(DatabasesXmlTags.ATT_minNbOfThreads);
01010     String maxNbOfThreads = atts.getValue(DatabasesXmlTags.ATT_maxNbOfThreads);
01011     String maxThreadIdleTime = atts
01012         .getValue(DatabasesXmlTags.ATT_maxThreadIdleTime);
01013     String sqlDumpLength = atts.getValue(DatabasesXmlTags.ATT_sqlDumpLength);
01014     String blobEncodingMethod = atts
01015         .getValue(DatabasesXmlTags.ATT_blobEncodingMethod);
01016 
01017     if (controller.hasVirtualDatabase(name))
01018     {
01019       String msg = Translate.get(
01020           "virtualdatabase.xml.virtualdatabase.already.exists", name);
01021       logger.error(msg);
01022       throw new SAXException(msg);
01023     }
01024 
01025     try
01026     {
01027       // Process the attributes
01028       int maxConnections = Integer.parseInt(maxNbOfConnections);
01029       boolean pool = poolThreads.equals(DatabasesXmlTags.VAL_true);
01030       int minThreads = Integer.parseInt(minNbOfThreads);
01031       int maxThreads = Integer.parseInt(maxNbOfThreads);
01032       // converts in ms
01033       long threadIdleTime = Long.parseLong(maxThreadIdleTime) * 1000L;
01034       int dumpLength = Integer.parseInt(sqlDumpLength);
01035       AbstractBlobFilter blobFilter = AbstractBlobFilter
01036           .getBlobFilterInstance(blobEncodingMethod);
01037       if (logger.isDebugEnabled())
01038         logger.debug(Translate.get(
01039             "virtualdatabase.xml.virtualdatabase.create", name));
01040       currentVirtualDatabase = new VirtualDatabase(controller, name,
01041           maxConnections, pool, minThreads, maxThreads, threadIdleTime,
01042           dumpLength, blobFilter);
01043 
01044     }
01045     catch (Exception e)
01046     {
01047       String msg = Translate.get("virtualdatabase.xml.virtualdatabase.failed");
01048       logger.error(msg, e);
01049       throw new SAXException(msg, e);
01050     }
01051   }
01052 
01053   /* Distribution */
01054 
01055   /**
01056    * Sets {@link #currentVirtualDatabase}as a new
01057    * <code>DistributedVirtalDatabase</code> using the parsed attributes.
01058    * 
01059    * @param atts parsed attributes
01060    */
01061   private void newDistribution(Attributes atts) throws SAXException
01062   {
01063     String groupName = atts.getValue(DatabasesXmlTags.ATT_groupName);
01064     String castTimeout = atts.getValue(DatabasesXmlTags.ATT_castTimeout);
01065     long timeout;
01066     try
01067     {
01068       timeout = Long.parseLong(castTimeout);
01069       CJDBCGroupMessage.defaultCastTimeOut = timeout;
01070     }
01071     catch (NumberFormatException e1)
01072     {
01073       // keep default
01074     }
01075 
01076     if (groupName == null)
01077       groupName = currentVirtualDatabase.getVirtualDatabaseName();
01078 
01079     if (logger.isDebugEnabled())
01080       logger.debug(Translate.get(
01081           "virtualdatabase.xml.virtualdatabase.distributed.create",
01082           new String[]{currentVirtualDatabase.getVirtualDatabaseName(),
01083               groupName, castTimeout}));
01084     try
01085     {
01086       // we need to replace previous database mbean
01087       ObjectName objectName = JmxConstants
01088           .getVirtualDbObjectName(currentVirtualDatabase
01089               .getVirtualDatabaseName());
01090       MBeanServerManager.unregister(objectName);
01091 
01092       currentVirtualDatabase = new DistributedVirtualDatabase(controller,
01093           currentVirtualDatabase.getVirtualDatabaseName(), groupName,
01094           currentVirtualDatabase.getMaxNbOfConnections(),
01095           currentVirtualDatabase.isPoolConnectionThreads(),
01096           currentVirtualDatabase.getMinNbOfThreads(), currentVirtualDatabase
01097               .getMaxNbOfThreads(), currentVirtualDatabase
01098               .getMaxThreadIdleTime(), currentVirtualDatabase
01099               .getSQLShortFormLength(), currentVirtualDatabase.getBlobFilter());
01100     }
01101     catch (Exception e)
01102     {
01103       String msg = Translate
01104           .get("virtualdatabase.xml.virtualdatabase.distributed.failed");
01105       logger.error(msg, e);
01106       throw new SAXException(msg, e);
01107     }
01108   }
01109 
01110   /**
01111    * Adds a new <code>BackendRecoveryPolicy</code> using the parsed
01112    * attributes.
01113    * 
01114    * @param atts parsed attributes
01115    * @throws SAXException if an error occurs
01116    */
01117   private void newBackendRecoveryPolicy(Attributes atts) throws SAXException
01118   {
01119     String backendName = atts.getValue(DatabasesXmlTags.ATT_backendName);
01120     String recoveryPolicyString = atts
01121         .getValue(DatabasesXmlTags.ATT_recoveryPolicy);
01122 
01123     boolean recoveryPolicy;
01124     if (recoveryPolicyString.equals(DatabasesXmlTags.VAL_on))
01125       recoveryPolicy = true;
01126     else if (recoveryPolicyString.equals(DatabasesXmlTags.VAL_off))
01127       recoveryPolicy = false;
01128     else
01129       throw new SAXException(
01130           Translate
01131               .get(
01132                   "virtualdatabase.xml.virtualdatabase.distributed.recoverOnFailure.bad.value",
01133                   recoveryPolicyString));
01134 
01135     currentBackendRecoveryPolicy = new BackendRecoveryPolicy(backendName,
01136         recoveryPolicy);
01137     ((DistributedVirtualDatabase) currentVirtualDatabase)
01138         .addBackendRecoveryPolicy(currentBackendRecoveryPolicy);
01139   }
01140 
01141   /**
01142    * Adds a new <code>ControllerName</code> to the current
01143    * <code>BackendRecoveryPolicy</code> using the parsed attributes.
01144    * 
01145    * @param atts parsed attributes
01146    * @throws SAXException if an error ocuurs
01147    */
01148   private void newControllerName(Attributes atts) throws SAXException
01149   {
01150     String name = atts.getValue(DatabasesXmlTags.ATT_name);
01151     try
01152     {
01153       currentBackendRecoveryPolicy.addController(name);
01154     }
01155     catch (ControllerException e)
01156     {
01157       throw new SAXException(e);
01158     }
01159   }
01160 
01161   /* Monitoring */
01162 
01163   /**
01164    * Sets a new <code>SQLMonitoring</code> to the current virtual database.
01165    * 
01166    * @param atts parsed attributes
01167    */
01168   private void newSQLMonitoring(Attributes atts)
01169   {
01170     String monitoringString = atts
01171         .getValue(DatabasesXmlTags.ATT_defaultMonitoring);
01172     boolean monitoring;
01173     if (monitoringString != null)
01174       monitoring = monitoringString.equals(DatabasesXmlTags.VAL_on);
01175     else
01176       monitoring = false;
01177 
01178     SQLMonitoring sqlMonitor = new SQLMonitoring(currentVirtualDatabase
01179         .getVirtualDatabaseName());
01180     sqlMonitor.setDefaultRule(monitoring);
01181     currentVirtualDatabase.setSQLMonitor(sqlMonitor);
01182   }
01183 
01184   /**
01185    * Add a new <code>SQLMonitoringRule</code> to the current SQL monitor.
01186    * 
01187    * @param atts parsed attributes
01188    */
01189   private void newSQLMonitoringRule(Attributes atts)
01190   {
01191     String queryPattern = atts.getValue(DatabasesXmlTags.ATT_queryPattern);
01192     String caseSensitiveString = atts
01193         .getValue(DatabasesXmlTags.ATT_caseSensitive);
01194     String applyToSkeletonString = atts
01195         .getValue(DatabasesXmlTags.ATT_applyToSkeleton);
01196     String monitoringString = atts.getValue(DatabasesXmlTags.ATT_monitoring);
01197 
01198     boolean caseSensitive;
01199     if (caseSensitiveString != null)
01200       caseSensitive = caseSensitiveString.equals(DatabasesXmlTags.VAL_true);
01201     else
01202       caseSensitive = false;
01203     boolean applyToSkeleton;
01204     if (applyToSkeletonString != null)
01205       applyToSkeleton = applyToSkeletonString.equals(DatabasesXmlTags.VAL_true);
01206     else
01207       applyToSkeleton = false;
01208     boolean monitoring;
01209     if (monitoringString != null)
01210       monitoring = monitoringString.equals(DatabasesXmlTags.VAL_on);
01211     else
01212       monitoring = false;
01213 
01214     // Create the rule and add it
01215     SQLMonitoringRule rule = new SQLMonitoringRule(queryPattern, caseSensitive,
01216         applyToSkeleton, monitoring);
01217 
01218     if (logger.isDebugEnabled())
01219       logger.debug(Translate.get("virtualdatabase.xml.sqlmonitoring.rule.add",
01220           new String[]{queryPattern, String.valueOf(caseSensitive),
01221               applyToSkeletonString, String.valueOf(monitoring)}));
01222     currentVirtualDatabase.getSQLMonitor().addRule(rule);
01223   }
01224 
01225   //
01226   // Backup
01227   //
01228 
01229   /**
01230    * Adds a new <code>BackupManager</code>
01231    * 
01232    * @param atts parsed attributes
01233    */
01234   private void newBackupManager(Attributes atts)
01235   {
01236     boolean zip = (Boolean.valueOf(atts.getValue(DatabasesXmlTags.ATT_zip)))
01237         .booleanValue();
01238     boolean clean = (Boolean.valueOf(atts.getValue(DatabasesXmlTags.ATT_clean)))
01239         .booleanValue();
01240     int number = -1;
01241     String dir = atts.getValue(DatabasesXmlTags.ATT_dir);
01242     currentBackupManager = new BackupManager();
01243     currentBackupManager.setBackupDir(dir);
01244     currentBackupManager.setCleanBackupFiles(clean);
01245     currentBackupManager.setZipBackupFiles(zip);
01246     currentBackupManager.setNumberOfBackups(number);
01247   }
01248 
01249   /* Database backend */
01250 
01251   /**
01252    * Sets {@link #currentBackend}as a new <code> DatabaseBackend</code> using
01253    * the parsed attributes.
01254    * 
01255    * @param atts parsed attributes
01256    * @throws SAXException
01257    */
01258   private void newDatabaseBackend(Attributes atts) throws SAXException
01259   {
01260     String name = atts.getValue(DatabasesXmlTags.ATT_name);
01261     String driverClassName = atts.getValue(DatabasesXmlTags.ATT_driver);
01262     String driverPath = atts.getValue(DatabasesXmlTags.ATT_driverPath);
01263     String url = atts.getValue(DatabasesXmlTags.ATT_url);
01264     String connectionTestStatement = atts
01265         .getValue(DatabasesXmlTags.ATT_connectionTestStatement);
01266 
01267     if (logger.isDebugEnabled())
01268     {
01269       logger.debug(Translate.get("virtualdatabase.xml.backend.create",
01270           new String[]{name, driverClassName, url, connectionTestStatement}));
01271       if (driverPath == null)
01272       {
01273         logger.debug("no driver path defined for backend.");
01274       }
01275       else
01276       {
01277         logger.debug("using driver path " + driverPath);
01278       }
01279     }
01280     try
01281     {
01282       currentBackend = new DatabaseBackend(name, driverPath, driverClassName,
01283           url, currentVirtualDatabase.getVirtualDatabaseName(), true,
01284           connectionTestStatement);
01285     }
01286     catch (NotCompliantMBeanException e)
01287     {
01288       logger.error("MBean is not compliant", e);
01289       throw new SAXException("mbean is not compliant");
01290     }
01291   }
01292 
01293   /**
01294    * Adds a <code>AbstractRewritingRule</code> to the current DatabaseBackend.
01295    * 
01296    * @param atts parsed attributes
01297    */
01298   private void newRewritingRule(Attributes atts) throws SAXException
01299   {
01300     String queryPattern = atts.getValue(DatabasesXmlTags.ATT_queryPattern);
01301     String rewrite = atts.getValue(DatabasesXmlTags.ATT_rewrite);
01302     String matchingType = atts.getValue(DatabasesXmlTags.ATT_matchingType);
01303     String caseSensitiveString = atts
01304         .getValue(DatabasesXmlTags.ATT_caseSensitive);
01305     String stopOnMatchString = atts.getValue(DatabasesXmlTags.ATT_stopOnMatch);
01306 
01307     boolean caseSensitive;
01308     if (caseSensitiveString != null)
01309       caseSensitive = caseSensitiveString.equals(DatabasesXmlTags.VAL_true);
01310     else
01311       caseSensitive = false;
01312     boolean stopOnMatch;
01313     if (stopOnMatchString != null)
01314       stopOnMatch = stopOnMatchString.equals(DatabasesXmlTags.VAL_true);
01315     else
01316       stopOnMatch = false;
01317 
01318     // Create the rule and add it
01319     AbstractRewritingRule rule;
01320     if (matchingType.equals(DatabasesXmlTags.VAL_simple))
01321       rule = new SimpleRewritingRule(queryPattern, rewrite, caseSensitive,
01322           stopOnMatch);
01323     else if (matchingType.equals(DatabasesXmlTags.VAL_pattern))
01324       rule = new PatternRewritingRule(queryPattern, rewrite, caseSensitive,
01325           stopOnMatch);
01326     else if (matchingType.equals(DatabasesXmlTags.VAL_replaceAll))
01327       rule = new ReplaceAllRewritingRule(queryPattern, rewrite, caseSensitive,
01328           stopOnMatch);
01329     else
01330       throw new SAXException(Translate.get(
01331           "virtualdatabase.xml.rewritingrule.unsupported.matching",
01332           matchingType));
01333 
01334     if (logger.isDebugEnabled())
01335       logger.debug(Translate.get("virtualdatabase.xml.rewritingrule.add",
01336           new String[]{queryPattern, rewrite, String.valueOf(caseSensitive),
01337               String.valueOf(stopOnMatch)}));
01338     currentBackend.addRewritingRule(rule);
01339   }
01340 
01341   /* Authentication manager */
01342 
01343   /**
01344    * Sets {@link #currentAuthenticationManager}as a new <code>
01345    * AuthenticationManager</code>.
01346    * 
01347    * @param atts not used attributes
01348    */
01349   private void newAuthenticationManager(Attributes atts)
01350   {
01351     currentAuthenticationManager = new AuthenticationManager();
01352   }
01353 
01354   /**
01355    * Sets the administrator user of the {@link #currentAuthenticationManager}
01356    * using the parsed attributs.
01357    * 
01358    * @param atts parsed attributes
01359    */
01360   private void newAdminUser(Attributes atts)
01361   {
01362     String aLogin = atts.getValue(DatabasesXmlTags.ATT_username);
01363     String aPassword = atts.getValue(DatabasesXmlTags.ATT_password);
01364 
01365     if (logger.isDebugEnabled())
01366       logger.debug(Translate.get(
01367           "virtualdatabase.xml.authentication.login.admin.add", new String[]{
01368               aLogin, aPassword}));
01369     currentAuthenticationManager.addAdminUser(new AdminUser(aLogin, aPassword));
01370   }
01371 
01372   /**
01373    * Sets {@link #currentVirtualUser}as a new <code> VirtualDatabaseUser
01374    * </code>
01375    * using the parsed attributes and adds this new virtual database user to the
01376    * {@link #currentAuthenticationManager}.
01377    * 
01378    * @param atts parsed attributes
01379    */
01380   private void newVirtualLogin(Attributes atts)
01381   {
01382     String vLogin = atts.getValue(DatabasesXmlTags.ATT_vLogin);
01383     String vPassword = atts.getValue(DatabasesXmlTags.ATT_vPassword);
01384     currentVirtualUser = new VirtualDatabaseUser(vLogin, vPassword);
01385 
01386     if (logger.isDebugEnabled())
01387       logger.debug(Translate.get(
01388           "virtualdatabase.xml.authentication.login.virtual.add", new String[]{
01389               vLogin, vPassword}));
01390     currentAuthenticationManager.addVirtualUser(currentVirtualUser);
01391   }
01392 
01393   /* Request manager */
01394 
01395   /**
01396    * Sets the {@link #beginTimeout},{@link #commitTimeout}and
01397    * {@link #rollbackTimeout}timeouts (in ms) using the parsed attributes.
01398    * 
01399    * @param atts element attributes
01400    * @exception SAXException if an error occurs
01401    */
01402   private void newRequestManager(Attributes atts) throws SAXException
01403   {
01404     try
01405     {
01406       String begin = atts.getValue(DatabasesXmlTags.ATT_beginTimeout);
01407       String commit = atts.getValue(DatabasesXmlTags.ATT_commitTimeout);
01408       String rollback = atts.getValue(DatabasesXmlTags.ATT_rollbackTimeout);
01409       String caseSensitiveParsingString = atts
01410           .getValue(DatabasesXmlTags.ATT_caseSensitiveParsing);
01411 
01412       // Convert to ms
01413       beginTimeout = Long.parseLong(begin) * 1000L;
01414       commitTimeout = Long.parseLong(commit) * 1000L;
01415       rollbackTimeout = Long.parseLong(rollback) * 1000L;
01416 
01417       if (caseSensitiveParsingString != null)
01418         caseSensitiveParsing = caseSensitiveParsingString
01419             .equals(DatabasesXmlTags.VAL_true);
01420       else
01421         caseSensitiveParsing = false;
01422 
01423       if (logger.isDebugEnabled())
01424         logger.debug(Translate.get(
01425             "virtualdatabase.xml.requestmanager.parameters", new String[]{
01426                 String.valueOf(beginTimeout), String.valueOf(commitTimeout),
01427                 String.valueOf(rollbackTimeout)}));
01428     }
01429     catch (NumberFormatException e)
01430     {
01431       String msg = Translate
01432           .get("virtualdatabase.xml.requestmanager.timeout.failed");
01433       logger.error(msg, e);
01434       throw new SAXException(msg, e);
01435     }
01436   }
01437 
01438   /* Macro Handling */
01439 
01440   /**
01441    * Adds a new <code>MacrosHandler</code> using the parsed attributes.
01442    * 
01443    * @param atts parsed attributes
01444    */
01445   private void newMacroHandler(Attributes atts)
01446   {
01447     /**
01448      * rand (off | int | long | float | double) "float" now (off | date | time |
01449      * timestamp) "timestamp" currentDate (off | date | time | timestamp) "date"
01450      * currentTime (off | date | time | timestamp) "time" timeOfDay (off | date |
01451      * time | timestamp) "timestamp" currentTimestamp (off | date | time |
01452      * timestamp) "timestamp" timeResolution CDATA "0"
01453      */
01454     String rand = atts.getValue(DatabasesXmlTags.ATT_rand);
01455     String now = atts.getValue(DatabasesXmlTags.ATT_now);
01456     String currentDate = atts.getValue(DatabasesXmlTags.ATT_currentDate);
01457     String currentTime = atts.getValue(DatabasesXmlTags.ATT_currentTime);
01458     String currentTimestamp = atts
01459         .getValue(DatabasesXmlTags.ATT_currentTimestamp);
01460     String timeResolution = atts.getValue(DatabasesXmlTags.ATT_timeResolution);
01461     String timeOfDay = atts.getValue(DatabasesXmlTags.ATT_timeOfDay);
01462 
01463     int icurrentDate = MacrosHandler.getIntDateLevel(currentDate);
01464     int icurrentTime = MacrosHandler.getIntDateLevel(currentTime);
01465     int icurrentTimestamp = MacrosHandler.getIntDateLevel(currentTimestamp);
01466     int itimeOfDay = MacrosHandler.getIntDateLevel(timeOfDay);
01467     int inow = MacrosHandler.getIntDateLevel(now);
01468     int irand = MacrosHandler.getIntRandLevel(rand);
01469     long ltimeResolution = Long.parseLong(timeResolution);
01470 
01471     try
01472     {
01473       currentMacroHandler = new MacrosHandler(irand, ltimeResolution, inow,
01474           icurrentDate, icurrentTime, itimeOfDay, icurrentTimestamp);
01475     }
01476     catch (RuntimeException e)
01477     {
01478       logger.warn(Translate.get(
01479           "virtualdatabase.xml.invalid.macroshandler.settings", e));
01480     }
01481   }
01482 
01483   /* Request scheduler */
01484 
01485   /**
01486    * Sets {@link #currentRequestScheduler}as a new <code>
01487    * SingleDBPassThroughScheduler</code>
01488    * using the parsed attributes.
01489    * 
01490    * @param atts parsed attributes
01491    * @exception SAXException if an error occurs
01492    */
01493   private void newSingleDBScheduler(Attributes atts) throws SAXException
01494   {
01495     String level = atts.getValue(DatabasesXmlTags.ATT_level);
01496 
01497     // SingleDB Query Level
01498     if (level.equals(DatabasesXmlTags.VAL_passThrough))
01499     {
01500       if (logger.isDebugEnabled())
01501         logger.debug(Translate
01502             .get("virtualdatabase.xml.scheduler.singledb.create.passthrough"));
01503       currentRequestScheduler = new SingleDBPassThroughScheduler();
01504     }
01505 
01506     // SingleDB Pessimistic Transaction Level
01507     else if (level.equals(DatabasesXmlTags.VAL_pessimisticTransaction))
01508     {
01509       if (logger.isDebugEnabled())
01510         logger.debug(Translate
01511             .get("virtualdatabase.xml.scheduler.singledb.create.pessimistic"));
01512       currentRequestScheduler = new SingleDBPessimisticTransactionLevelScheduler();
01513     }
01514     else
01515     {
01516       throw new SAXException(Translate.get(
01517           "virtualdatabase.xml.scheduler.singledb.unsupported", level));
01518     }
01519   }
01520 
01521   /**
01522    * Sets {@link #currentRequestScheduler}as a new <code>
01523    * RAIDb0PassThroughLevelScheduler</code>
01524    * or <code>RAIDb0PessimisticTransactionLevelScheduler</code> using the
01525    * parsed attributes.
01526    * 
01527    * @param atts parsed attributes
01528    * @exception SAXException if an error occurs
01529    */
01530   private void newRAIDb0Scheduler(Attributes atts) throws SAXException
01531   {
01532     String level = atts.getValue(DatabasesXmlTags.ATT_level);
01533 
01534     if (level.equals(DatabasesXmlTags.VAL_passThrough))
01535     {
01536       if (logger.isDebugEnabled())
01537         logger.debug(Translate
01538             .get("virtualdatabase.xml.scheduler.raidb0.create.passthrough"));
01539       currentRequestScheduler = new RAIDb0PassThroughLevelScheduler();
01540     }
01541     else if (level.equals(DatabasesXmlTags.VAL_pessimisticTransaction))
01542     {
01543       if (logger.isDebugEnabled())
01544         logger.debug(Translate
01545             .get("virtualdatabase.xml.scheduler.raidb0.create.pessimistic"));
01546       currentRequestScheduler = new RAIDb0PessimisticTransactionLevelScheduler();
01547     }
01548     else
01549       throw new SAXException(Translate.get(
01550           "virtualdatabase.xml.scheduler.raidb0.unsupported", level));
01551   }
01552 
01553   /**
01554    * Sets {@link #currentRequestScheduler}as a new
01555    * <code>RAIDb1PassThroughScheduler</code>,<code>
01556    * RAIDb1QueryLevelScheduler</code>,
01557    * <code>RAIDb1OptimisticQueryLevelScheduler</code> or
01558    * <code>RAIDb1PessimisticTransactionLevelScheduler</code> using the parsed
01559    * attributes.
01560    * 
01561    * @param atts parsed attributes
01562    * @exception SAXException if an error occurs
01563    */
01564   private void newRAIDb1Scheduler(Attributes atts) throws SAXException
01565   {
01566     String level = atts.getValue(DatabasesXmlTags.ATT_level);
01567 
01568     // RAIDb-1 Pass Through level
01569     if (level.equals(DatabasesXmlTags.VAL_passThrough))
01570     {
01571       if (logger.isDebugEnabled())
01572         logger.debug(Translate
01573             .get("virtualdatabase.xml.scheduler.raidb1.create.passthrough"));
01574       currentRequestScheduler = new RAIDb1PassThroughScheduler();
01575     }
01576     // RAIDb-1 Query level
01577     else if (level.equals(DatabasesXmlTags.VAL_query))
01578     {
01579       if (logger.isDebugEnabled())
01580         logger.debug(Translate
01581             .get("virtualdatabase.xml.scheduler.raidb1.create.query"));
01582       currentRequestScheduler = new RAIDb1QueryLevelScheduler();
01583     }
01584     // RAIDb-1 Optimistic Query level
01585     else if (level.equals(DatabasesXmlTags.VAL_optimisticQuery))
01586     {
01587       if (logger.isDebugEnabled())
01588         logger
01589             .debug(Translate
01590                 .get("virtualdatabase.xml.scheduler.raidb1.create.query.optimistic"));
01591       currentRequestScheduler = new RAIDb1OptimisticQueryLevelScheduler();
01592     }
01593     // RAIDb-1 Optimistic Transaction level
01594     else if (level.equals(DatabasesXmlTags.VAL_optimisticTransaction))
01595     {
01596       if (logger.isDebugEnabled())
01597         logger.debug(Translate
01598             .get("virtualdatabase.xml.scheduler.raidb1.create.optimistic"));
01599       currentRequestScheduler = new RAIDb1OptimisticTransactionLevelScheduler();
01600     }
01601     // RAIDb-1 Pessimistic Transaction level
01602     else if (level.equals(DatabasesXmlTags.VAL_pessimisticTransaction))
01603     {
01604       if (logger.isDebugEnabled())
01605         logger.debug(Translate
01606             .get("virtualdatabase.xml.scheduler.raidb1.create.pessimistic"));
01607       currentRequestScheduler = new RAIDb1PessimisticTransactionLevelScheduler();
01608     }
01609     else
01610     {
01611       throw new SAXException(Translate.get(
01612           "virtualdatabase.xml.scheduler.raidb1.unsupported", level));
01613     }
01614   }
01615 
01616   /**
01617    * Sets {@link #currentRequestScheduler}as a new
01618    * <code>RAIDb2PassThroughLevelScheduler</code>,<code>
01619    * RAIDb2QueryLevelScheduler</code>
01620    * or <code>RAIDb2PessimisticTransactionLevelScheduler</code> using the
01621    * parsed attributes.
01622    * 
01623    * @param atts parsed attributes
01624    * @exception SAXException if an error occurs
01625    */
01626   private void newRAIDb2Scheduler(Attributes atts) throws SAXException
01627   {
01628     String level = atts.getValue(DatabasesXmlTags.ATT_level);
01629 
01630     // RAIDb-2 Query level
01631     if (level.equals(DatabasesXmlTags.VAL_passThrough))
01632     {
01633       if (logger.isDebugEnabled())
01634         logger.debug(Translate
01635             .get("virtualdatabase.xml.scheduler.raidb2.create.passthrough"));
01636       currentRequestScheduler = new RAIDb2PassThroughLevelScheduler();
01637     }
01638     // RAIDb-2 Query level
01639     else if (level.equals(DatabasesXmlTags.VAL_query))
01640     {
01641       if (logger.isDebugEnabled())
01642         logger.debug(Translate
01643             .get("virtualdatabase.xml.scheduler.raidb2.create.query"));
01644       currentRequestScheduler = new RAIDb2QueryLevelScheduler();
01645     }
01646     // RAIDb-2 Pessimistic Transaction level
01647     else if (level.equals(DatabasesXmlTags.VAL_pessimisticTransaction))
01648     {
01649       if (logger.isDebugEnabled())
01650         logger.debug(Translate
01651             .get("virtualdatabase.xml.scheduler.raidb2.create.pessimistic"));
01652       currentRequestScheduler = new RAIDb2PessimisticTransactionLevelScheduler();
01653     }
01654     else
01655     {
01656       throw new SAXException(Translate.get(
01657           "virtualdatabase.xml.scheduler.raidb2.unsupported", level));
01658     }
01659   }
01660 
01661   /* ********************** */
01662   /* *** Request caches *** */
01663   /* ********************** */
01664 
01665   /**
01666    * Sets {@link #currentMetadataCache}as a new <code>MetadataCache</code>
01667    * using the parsed attributes.
01668    * 
01669    * @param atts parsed attributes
01670    * @exception SAXException if an error occurs
01671    */
01672   private void newMetadataCache(Attributes atts) throws SAXException
01673   {
01674     try
01675     {
01676       int maxMetadata = Integer.parseInt(atts
01677           .getValue(DatabasesXmlTags.ATT_maxNbOfMetadata));
01678       int maxField = Integer.parseInt(atts
01679           .getValue(DatabasesXmlTags.ATT_maxNbOfField));
01680       currentMetadataCache = new MetadataCache(maxMetadata, maxField);
01681     }
01682     catch (Exception e)
01683     {
01684       String msg = Translate.get(
01685           "virtualdatabase.xml.metadata.cache.create.failed", e);
01686       logger.error(msg, e);
01687       throw new SAXException(msg, e);
01688     }
01689   }
01690 
01691   /**
01692    * Sets {@link #currentParsingCache}as a new <code>ParsingCache</code>
01693    * using the parsed attributes.
01694    * 
01695    * @param atts parsed attributes
01696    * @exception SAXException if an error occurs
01697    */
01698   private void newParsingCache(Attributes atts) throws SAXException
01699   {
01700     String backgroundParsingString = atts
01701         .getValue(DatabasesXmlTags.ATT_backgroundParsing);
01702     boolean backgroundParsing;
01703 
01704     if (backgroundParsingString != null)
01705       backgroundParsing = backgroundParsingString
01706           .equals(DatabasesXmlTags.VAL_true);
01707     else
01708       backgroundParsing = false;
01709 
01710     String maxEntriesString = atts
01711         .getValue(DatabasesXmlTags.ATT_maxNbOfEntries);
01712     int maxEntries = Integer.parseInt(maxEntriesString);
01713 
01714     try
01715     {
01716       currentParsingCache = new ParsingCache(maxEntries, backgroundParsing);
01717     }
01718     catch (Exception e)
01719     {
01720       String msg = Translate.get(
01721           "virtualdatabase.xml.parsing.cache.create.failed", e);
01722       logger.error(msg, e);
01723       throw new SAXException(msg, e);
01724     }
01725   }
01726 
01727   /**
01728    * Sets {@link #currentResultCache}as a new <code> ResultCache</code> using
01729    * the parsed attributes.
01730    * 
01731    * @param atts parsed attributes
01732    * @exception SAXException if an error occurs
01733    */
01734   private void newResultCache(Attributes atts) throws SAXException
01735   {
01736     String granularity = atts.getValue(DatabasesXmlTags.ATT_granularity);
01737     String maxEntriesString = atts
01738         .getValue(DatabasesXmlTags.ATT_maxNbOfEntries);
01739     String pendingTimeoutString = atts
01740         .getValue(DatabasesXmlTags.ATT_pendingTimeout);
01741 
01742     if (logger.isDebugEnabled())
01743       logger.debug(Translate.get("virtualdatabase.xml.cache.create",
01744           granularity));
01745 
01746     try
01747     {
01748       int maxEntries = Integer.parseInt(maxEntriesString);
01749       int pendingTimeout = Integer.parseInt(pendingTimeoutString);
01750 
01751       int granularityValue;
01752       if (granularity.equals(DatabasesXmlTags.VAL_table))
01753         granularityValue = CachingGranularities.TABLE;
01754       else if (granularity.equals(DatabasesXmlTags.VAL_database))
01755         granularityValue = CachingGranularities.DATABASE;
01756       else if (granularity.equals(DatabasesXmlTags.VAL_column))
01757         granularityValue = CachingGranularities.COLUMN;
01758       else if (granularity.equals(DatabasesXmlTags.VAL_columnUnique))
01759         granularityValue = CachingGranularities.COLUMN_UNIQUE;
01760       else
01761         throw new InstantiationException(Translate.get(
01762             "virtualdatabase.xml.cache.unsupported", granularity));
01763 
01764       currentResultCache = ResultCacheFactory.getCacheInstance(
01765           granularityValue, maxEntries, pendingTimeout);
01766 
01767     }
01768     catch (Exception e)
01769     {
01770       String msg = Translate.get("virtualdatabase.xml.cache.create.failed",
01771           granularity);
01772       logger.error(msg, e);
01773       throw new SAXException(msg, e);
01774     }
01775   }
01776 
01777   /**
01778    * Add a new <code>ResultCacheRule</code> using the parsed attributes.
01779    * 
01780    * @param atts parsed attributes
01781    * @exception SAXException if an error occurs
01782    */
01783   private void newResultCacheRule(Attributes atts) throws SAXException
01784   {
01785     String queryString = atts.getValue(DatabasesXmlTags.ATT_queryPattern);
01786 
01787     String caseSensitiveString = atts
01788         .getValue(DatabasesXmlTags.ATT_caseSensitive);
01789     String applyToSkeletonString = atts
01790         .getValue(DatabasesXmlTags.ATT_applyToSkeleton);
01791     long timestampResolution;
01792     try
01793     {
01794       timestampResolution = Long.parseLong(atts
01795           .getValue(DatabasesXmlTags.ATT_timestampResolution));
01796       timestampResolution *= 1000;
01797     }
01798     catch (Exception e)
01799     {
01800       logger
01801           .warn(Translate.get("virtualdatabase.invalid.timestamp.resolution"));
01802       timestampResolution = 1000;
01803     }
01804 
01805     boolean caseSensitive;
01806     if (caseSensitiveString != null)
01807       caseSensitive = caseSensitiveString.equals(DatabasesXmlTags.VAL_true);
01808     else
01809       caseSensitive = false;
01810     boolean applyToSkeleton;
01811     if (applyToSkeletonString != null)
01812       applyToSkeleton = applyToSkeletonString.equals(DatabasesXmlTags.VAL_true);
01813     else
01814       applyToSkeleton = false;
01815 
01816     // Create the rule
01817     try
01818     {
01819       currentResultCacheRule = new ResultCacheRule(queryString, caseSensitive,
01820           applyToSkeleton, timestampResolution);
01821     }
01822     catch (RESyntaxException e1)
01823     {
01824       String msg = Translate.get("virtualdatabase.xml.cache.rule.invalid", e1);
01825       logger.error(msg);
01826       throw new SAXException(msg);
01827     }
01828 
01829     if (logger.isDebugEnabled())
01830       logger.debug(Translate.get("virtualdatabase.xml.cache.rule.add",
01831           new String[]{atts.getValue(DatabasesXmlTags.ATT_queryPattern),
01832               String.valueOf(caseSensitive), applyToSkeletonString,
01833               String.valueOf(timestampResolution)}));
01834     currentResultCache.addCachingRule(currentResultCacheRule);
01835   }
01836 
01837   /**
01838    * Set the <code>DefaultResultCacheRule</code> using the parsed attributes.
01839    * 
01840    * @param atts parsed attributes
01841    * @exception SAXException if an error occurs
01842    */
01843   private void newDefaultResultCacheRule(Attributes atts) throws SAXException
01844   {
01845     long currentTimestampResolution;
01846     try
01847     {
01848       currentTimestampResolution = Long.parseLong(atts
01849           .getValue(DatabasesXmlTags.ATT_timestampResolution)) / 1000;
01850     }
01851     catch (Exception e)
01852     {
01853       String msg = Translate
01854           .get("virtualdatabase.invalid.timestamp.resolution");
01855       logger.warn(msg);
01856       currentTimestampResolution = 1000;
01857     }
01858     // Create a fake rule
01859     try
01860     {
01861       currentResultCacheRule = new ResultCacheRule("", false, false,
01862           currentTimestampResolution);
01863     }
01864     catch (RESyntaxException e)
01865     {
01866       throw new SAXException(Translate.get(
01867           "virtualdatabase.xml.cache.rule.default.invalid", e));
01868     }
01869   }
01870 
01871   /**
01872    * Add a new <code>EagerCaching</code> behavior to the current
01873    * <code>ResultCacheRule</code>.
01874    * 
01875    * @param atts parsed attributes
01876    * @exception SAXException if an error occurs
01877    */
01878   private void newEagerCaching(Attributes atts)
01879   {
01880     Hashtable options = new Hashtable();
01881     for (int i = 0; i < atts.getLength(); i++)
01882       options.put(atts.getQName(i), atts.getValue(i));
01883     currentResultCacheRule.setCacheBehavior(ResultCacheFactory
01884         .getCacheBehaviorInstance(DatabasesXmlTags.ELT_EagerCaching, options));
01885   }
01886 
01887   /**
01888    * Add a new <code>RelaxedCaching</code> behavior to the current
01889    * <code>ResultCacheRule</code>.
01890    * 
01891    * @param atts parsed attributes
01892    */
01893   private void newRelaxedCaching(Attributes atts)
01894   {
01895     Hashtable options = new Hashtable();
01896     for (int i = 0; i < atts.getLength(); i++)
01897       options.put(atts.getQName(i), atts.getValue(i));
01898     currentResultCacheRule
01899         .setCacheBehavior(ResultCacheFactory.getCacheBehaviorInstance(
01900             DatabasesXmlTags.ELT_RelaxedCaching, options));
01901   }
01902 
01903   /* Load balancers */
01904 
01905   /**
01906    * Sets {@link #currentLoadBalancer}as a new <code> SingleDB</code> using
01907    * the parsed attributes.
01908    * 
01909    * @param atts parsed attributes
01910    * @exception SAXException if an error occurs
01911    */
01912   private void newSingleDBRequestLoadBalancer(Attributes atts)
01913       throws SAXException
01914   {
01915     if (logger.isDebugEnabled())
01916       logger.debug(Translate
01917           .get("virtualdatabase.xml.loadbalancer.singledb.set"));
01918 
01919     try
01920     {
01921       currentLoadBalancer = new SingleDB(currentVirtualDatabase);
01922     }
01923     catch (Exception e)
01924     {
01925       String msg = Translate
01926           .get("virtualdatabase.xml.loadbalancer.singledb.failed");
01927       logger.error(msg, e);
01928       throw new SAXException(msg, e);
01929     }
01930   }
01931 
01932   //
01933   // ParallelDB load balancers
01934   //
01935 
01936   /**
01937    * Sets {@link #currentLoadBalancer}as a new <code>ParallelDB_RR</code>
01938    * using the parsed attributes.
01939    * 
01940    * @param atts parsed attributes
01941    * @exception SAXException if an error occurs
01942    */
01943   private void newParallelDBLeastPendingRequestsFirst(Attributes atts)
01944       throws SAXException
01945   {
01946     if (logger.isDebugEnabled())
01947       logger.debug(Translate
01948           .get("virtualdatabase.xml.loadbalancer.paralleldb_rr.set"));
01949 
01950     try
01951     {
01952       currentLoadBalancer = new ParallelDB_RR(currentVirtualDatabase);
01953     }
01954     catch (Exception e)
01955     {
01956       String msg = Translate
01957           .get("virtualdatabase.xml.loadbalancer.paralleldb_rr.failed");
01958       logger.error(msg, e);
01959       throw new SAXException(msg, e);
01960     }
01961   }
01962 
01963   /**
01964    * Sets {@link #currentLoadBalancer}as a new <code>ParallelDB_LPRF</code>
01965    * using the parsed attributes.
01966    * 
01967    * @param atts parsed attributes
01968    * @exception SAXException if an error occurs
01969    */
01970   private void newParallelDBRoundRobinLoadBalancer(Attributes atts)
01971       throws SAXException
01972   {
01973     if (logger.isDebugEnabled())
01974       logger.debug(Translate
01975           .get("virtualdatabase.xml.loadbalancer.paralleldb_lprf.set"));
01976 
01977     try
01978     {
01979       currentLoadBalancer = new ParallelDB_LPRF(currentVirtualDatabase);
01980     }
01981     catch (Exception e)
01982     {
01983       String msg = Translate
01984           .get("virtualdatabase.xml.loadbalancer.paralleldb_lprf.failed");
01985       logger.error(msg, e);
01986       throw new SAXException(msg, e);
01987     }
01988   }
01989 
01990   //
01991   // RAIDb-0 load balancers
01992   //
01993 
01994   /**
01995    * Sets {@link #currentLoadBalancer}as a new <code> RAIDb0</code> using the
01996    * parsed attributes.
01997    * 
01998    * @param atts parsed attributes
01999    */
02000   private void newRAIDb0LoadBalancer(Attributes atts)
02001   {
02002     currentCreateTablePolicy = new CreateTablePolicy();
02003     currentCreateTableRule = null;
02004   }
02005 
02006   //
02007   // RAIDb-1 load balancers
02008   //
02009 
02010   /**
02011    * Sets {@link #currentLoadBalancer}as a new <code> RAIDb1</code> using the
02012    * parsed attributes.
02013    * 
02014    * @param atts parsed attributes
02015    */
02016   private void newRAIDb1LoadBalancer(Attributes atts)
02017   {
02018     currentWaitForCompletionPolicy = null;
02019   }
02020 
02021   /**
02022    * Sets {@link #currentLoadBalancer}as a new <code> RAIDb1_RR</code> using
02023    * the parsed attributes.
02024    * 
02025    * @param atts parsed attributes
02026    * @exception SAXException if an error occurs
02027    */
02028   private void newRAIDb1RoundRobinLoadBalancer(Attributes atts)
02029       throws SAXException
02030   {
02031     if (currentWaitForCompletionPolicy == null)
02032       currentWaitForCompletionPolicy = new WaitForCompletionPolicy();
02033 
02034     if (logger.isDebugEnabled())
02035     {
02036       logger.debug(Translate
02037           .get("virtualdatabase.xml.loadbalancer.raidb1_rr.set"));
02038       logger.debug(Translate.get(
02039           "virtualdatabase.xml.loadbalancer.waitforcompletion.rule",
02040           currentWaitForCompletionPolicy.getInformation()));
02041     }
02042 
02043     try
02044     {
02045       currentLoadBalancer = new RAIDb1_RR(currentVirtualDatabase,
02046           currentWaitForCompletionPolicy);
02047     }
02048     catch (Exception e)
02049     {
02050       String msg = Translate
02051           .get("virtualdatabase.xml.loadbalancer.raidb1_rr.failed");
02052       logger.error(msg, e);
02053       throw new SAXException(msg, e);
02054     }
02055   }
02056 
02057   /**
02058    * Sets {@link #currentLoadBalancer}as a new <code> RAIDb1_WRR</code> using
02059    * the parsed attributes.
02060    * 
02061    * @param atts parsed attributes
02062    * @exception SAXException if an error occurs
02063    */
02064   private void newRAIDb1WeightedRoundRobinLoadBalancer(Attributes atts)
02065       throws SAXException
02066   {
02067     if (currentWaitForCompletionPolicy == null)
02068       currentWaitForCompletionPolicy = new WaitForCompletionPolicy();
02069 
02070     if (logger.isDebugEnabled())
02071     {
02072       logger.debug(Translate
02073           .get("virtualdatabase.xml.loadbalancer.raidb1_wrr.set"));
02074       logger.debug(Translate.get(
02075           "virtualdatabase.xml.loadbalancer.waitforcompletion.rule",
02076           currentWaitForCompletionPolicy.getInformation()));
02077     }
02078 
02079     try
02080     {
02081       currentLoadBalancer = new RAIDb1_WRR(currentVirtualDatabase,
02082           currentWaitForCompletionPolicy);
02083     }
02084     catch (Exception e)
02085     {
02086       String msg = Translate
02087           .get("virtualdatabase.xml.loadbalancer.raidb1_wrr.failed");
02088       logger.error(msg, e);
02089       throw new SAXException(msg, e);
02090     }
02091   }
02092 
02093   /**
02094    * Sets {@link #currentLoadBalancer}as a new <code> RAIDb1_LPRF</code> using
02095    * the parsed attributes.
02096    * 
02097    * @param atts parsed attributes
02098    * @exception SAXException if an error occurs
02099    */
02100   private void newRAIDb1LeastPendingRequestsFirst(Attributes atts)
02101       throws SAXException
02102   {
02103     if (currentWaitForCompletionPolicy == null)
02104       currentWaitForCompletionPolicy = new WaitForCompletionPolicy();
02105 
02106     if (logger.isDebugEnabled())
02107     {
02108       logger.debug(Translate
02109           .get("virtualdatabase.xml.loadbalancer.raidb1_lprf.set"));
02110       logger.debug(Translate.get(
02111           "virtualdatabase.xml.loadbalancer.waitforcompletion.rule",
02112           currentWaitForCompletionPolicy.getInformation()));
02113     }
02114 
02115     try
02116     {
02117       currentLoadBalancer = new RAIDb1_LPRF(currentVirtualDatabase,
02118           currentWaitForCompletionPolicy);
02119     }
02120     catch (Exception e)
02121     {
02122       String msg = Translate
02123           .get("virtualdatabase.xml.loadbalancer.raidb1_lprf.failed");
02124       logger.error(msg, e);
02125       throw new SAXException(msg, e);
02126     }
02127   }
02128 
02129   //
02130   // RAIDb-1ec load balancers
02131   //
02132 
02133   /**
02134    * Sets {@link #currentLoadBalancer}as a new <code> RAIDb1ec</code> using
02135    * the parsed attributes.
02136    * 
02137    * @param atts parsed attributes
02138    */
02139   private void newRAIDb1ecLoadBalancer(Attributes atts)
02140   {
02141     String nbOfConcurrentReads = atts
02142         .getValue(DatabasesXmlTags.ATT_nbOfConcurrentReads);
02143     currentNbOfConcurrentReads = Integer.parseInt(nbOfConcurrentReads);
02144     currentErrorCheckingPolicy = null;
02145     currentWaitForCompletionPolicy = null;
02146   }
02147 
02148   /**
02149    * Sets {@link #currentLoadBalancer}as a new <code> RAIDb1ec_RR</code> using
02150    * the parsed attributes.
02151    * 
02152    * @param atts parsed attributes
02153    * @exception SAXException if an error occurs
02154    */
02155   private void newRAIDb1ecRoundRobinLoadBalancer(Attributes atts)
02156       throws SAXException
02157   {
02158     if (currentWaitForCompletionPolicy == null)
02159       currentWaitForCompletionPolicy = new WaitForCompletionPolicy();
02160 
02161     if (logger.isDebugEnabled())
02162     {
02163       logger.debug(Translate
02164           .get("virtualdatabase.xml.loadbalancer.raidb1ec_rr.set"));
02165       logger.debug(Translate.get(
02166           "virtualdatabase.xml.loadbalancer.waitforcompletion.rule",
02167           currentWaitForCompletionPolicy.getInformation()));
02168     }
02169 
02170     try
02171     {
02172       currentLoadBalancer = new RAIDb1ec_RR(currentVirtualDatabase,
02173           currentWaitForCompletionPolicy, currentErrorCheckingPolicy,
02174           currentNbOfConcurrentReads);
02175       if (logger.isDebugEnabled())
02176         logger.debug(Translate.get(
02177             "virtualdatabase.xml.loadbalancer.errorchecking.policy",
02178             currentErrorCheckingPolicy.getInformation()));
02179     }
02180     catch (Exception e)
02181     {
02182       String msg = Translate
02183           .get("virtualdatabase.xml.loadbalancer.raidb1ec_rr.failed");
02184       logger.error(msg, e);
02185       throw new SAXException(msg, e);
02186     }
02187   }
02188 
02189   /**
02190    * Sets {@link #currentLoadBalancer}as a new <code> RAIDb1ec_WRR</code>
02191    * using the parsed attributes.
02192    * 
02193    * @param atts parsed attributes
02194    * @exception SAXException if an error occurs
02195    */
02196   private void newRAIDb1ecWeightedRoundRobinLoadBalancer(Attributes atts)
02197       throws SAXException
02198   {
02199     if (currentWaitForCompletionPolicy == null)
02200       currentWaitForCompletionPolicy = new WaitForCompletionPolicy();
02201 
02202     if (logger.isDebugEnabled())
02203     {
02204       logger.debug(Translate
02205           .get("virtualdatabase.xml.loadbalancer.raidb1ec_wrr.set"));
02206       logger.debug(Translate.get(
02207           "virtualdatabase.xml.loadbalancer.waitforcompletion.rule",
02208           currentWaitForCompletionPolicy.getInformation()));
02209     }
02210 
02211     try
02212     {
02213       currentLoadBalancer = new RAIDb1ec_WRR(currentVirtualDatabase,
02214           currentWaitForCompletionPolicy, currentErrorCheckingPolicy,
02215           currentNbOfConcurrentReads);
02216       if (logger.isDebugEnabled())
02217         logger.debug(Translate.get(
02218             "virtualdatabase.xml.loadbalancer.errorchecking.policy",
02219             currentErrorCheckingPolicy.getInformation()));
02220     }
02221     catch (Exception e)
02222     {
02223       String msg = Translate
02224           .get("virtualdatabase.xml.loadbalancer.raidb1ec_wrr.failed");
02225       logger.error(msg, e);
02226       throw new SAXException(msg, e);
02227     }
02228   }
02229 
02230   //
02231   // RAIDb-2 load balancers
02232   //
02233 
02234   /**
02235    * Sets {@link #currentLoadBalancer}as a new <code> RAIDb2</code> using the
02236    * parsed attributes.
02237    * 
02238    * @param atts parsed attributes
02239    */
02240   private void newRAIDb2LoadBalancer(Attributes atts)
02241   {
02242     currentWaitForCompletionPolicy = null;
02243     currentCreateTablePolicy = new CreateTablePolicy();
02244     // Add a default rule to create table on all nodes
02245     currentCreateTablePolicy.addRule(new CreateTableAll());
02246     currentCreateTableRule = null;
02247   }
02248 
02249   /**
02250    * Sets {@link #currentLoadBalancer}as a new <code> RAIDb2_RR</code> using
02251    * the parsed attributes.
02252    * 
02253    * @param atts parsed attributes
02254    * @exception SAXException if an error occurs
02255    */
02256   private void newRAIDb2RoundRobinLoadBalancer(Attributes atts)
02257       throws SAXException
02258   {
02259     if (currentWaitForCompletionPolicy == null)
02260       currentWaitForCompletionPolicy = new WaitForCompletionPolicy();
02261 
02262     if (logger.isDebugEnabled())
02263     {
02264       logger.debug(Translate
02265           .get("virtualdatabase.xml.loadbalancer.raidb2_rr.set"));
02266       logger.debug(Translate.get(
02267           "virtualdatabase.xml.loadbalancer.waitforcompletion.rule",
02268           currentWaitForCompletionPolicy.getInformation()));
02269     }
02270 
02271     try
02272     {
02273       currentLoadBalancer = new RAIDb2_RR(currentVirtualDatabase,
02274           currentWaitForCompletionPolicy, currentCreateTablePolicy);
02275     }
02276     catch (Exception e)
02277     {
02278       String msg = Translate
02279           .get("virtualdatabase.xml.loadbalancer.raidb2_rr.failed");
02280       logger.error(msg, e);
02281       throw new SAXException(msg, e);
02282     }
02283   }
02284 
02285   /**
02286    * Sets {@link #currentLoadBalancer}as a new <code> RAIDb2_WRR</code> using
02287    * the parsed attributes.
02288    * 
02289    * @param atts parsed attributes
02290    * @exception SAXException if an error occurs
02291    */
02292   private void newRAIDb2WeightedRoundRobinLoadBalancer(Attributes atts)
02293       throws SAXException
02294   {
02295     if (currentWaitForCompletionPolicy == null)
02296       currentWaitForCompletionPolicy = new WaitForCompletionPolicy();
02297 
02298     if (logger.isDebugEnabled())
02299     {
02300       logger.debug(Translate
02301           .get("virtualdatabase.xml.loadbalancer.raidb2_wrr.set"));
02302       logger.debug(Translate.get(
02303           "virtualdatabase.xml.loadbalancer.waitforcompletion.rule",
02304           currentWaitForCompletionPolicy.getInformation()));
02305     }
02306 
02307     try
02308     {
02309       currentLoadBalancer = new RAIDb2_WRR(currentVirtualDatabase,
02310           currentWaitForCompletionPolicy, currentCreateTablePolicy);
02311     }
02312     catch (Exception e)
02313     {
02314       String msg = Translate
02315           .get("virtualdatabase.xml.loadbalancer.raidb2_wrr.failed");
02316       logger.error(msg, e);
02317       throw new SAXException(msg, e);
02318     }
02319   }
02320 
02321   /**
02322    * Sets {@link #currentLoadBalancer}as a new <code> RAIDb2_LPRF</code> using
02323    * the parsed attributes.
02324    * 
02325    * @param atts parsed attributes
02326    * @exception SAXException if an error occurs
02327    */
02328   private void newRAIDb2LeastPendingRequestsFirst(Attributes atts)
02329       throws SAXException
02330   {
02331     if (currentWaitForCompletionPolicy == null)
02332       currentWaitForCompletionPolicy = new WaitForCompletionPolicy();
02333     if (logger.isDebugEnabled())
02334     {
02335       logger.debug(Translate
02336           .get("virtualdatabase.xml.loadbalancer.raidb2_lprf.set"));
02337       logger.debug(Translate.get(
02338           "virtualdatabase.xml.loadbalancer.waitforcompletion.rule",
02339           currentWaitForCompletionPolicy.getInformation()));
02340     }
02341 
02342     try
02343     {
02344       currentLoadBalancer = new RAIDb2_LPRF(currentVirtualDatabase,
02345           currentWaitForCompletionPolicy, currentCreateTablePolicy);
02346     }
02347     catch (Exception e)
02348     {
02349       String msg = Translate
02350           .get("virtualdatabase.xml.loadbalancer.raidb2_lprf.failed");
02351       logger.error(msg, e);
02352       throw new SAXException(msg, e);
02353     }
02354   }
02355 
02356   //
02357   // RAIDb-2ec load balancers
02358   //
02359 
02360   /**
02361    * Sets {@link #currentLoadBalancer}as a new <code> RAIDb2ec</code> using
02362    * the parsed attributes.
02363    * 
02364    * @param atts parsed attributes
02365    */
02366   private void newRAIDb2ecLoadBalancer(Attributes atts)
02367   {
02368     currentErrorCheckingPolicy = null;
02369     currentWaitForCompletionPolicy = null;
02370     currentCreateTablePolicy = new CreateTablePolicy();
02371     currentCreateTableRule = null;
02372   }
02373 
02374   /**
02375    * Sets {@link #currentLoadBalancer}as a new <code> RAIDb2ec_RR</code> using
02376    * the parsed attributes.
02377    * 
02378    * @param atts parsed attributes
02379    * @exception SAXException if an error occurs
02380    */
02381   private void newRAIDb2ecRoundRobinLoadBalancer(Attributes atts)
02382       throws SAXException
02383   {
02384     if (currentWaitForCompletionPolicy == null)
02385       currentWaitForCompletionPolicy = new WaitForCompletionPolicy();
02386 
02387     if (logger.isDebugEnabled())
02388     {
02389       logger.debug(Translate
02390           .get("virtualdatabase.xml.loadbalancer.raidb2_rr.set"));
02391       logger.debug(Translate.get(
02392           "virtualdatabase.xml.loadbalancer.waitforcompletion.rule",
02393           currentWaitForCompletionPolicy.getInformation()));
02394     }
02395 
02396     try
02397     {
02398       currentLoadBalancer = new RAIDb2ec_RR(currentVirtualDatabase,
02399           currentWaitForCompletionPolicy, currentCreateTablePolicy,
02400           currentErrorCheckingPolicy, currentNbOfConcurrentReads);
02401       if (logger.isDebugEnabled())
02402         logger.debug(Translate.get(
02403             "virtualdatabase.xml.loadbalancer.errorchecking.policy",
02404             currentErrorCheckingPolicy.getInformation()));
02405     }
02406     catch (Exception e)
02407     {
02408       String msg = Translate
02409           .get("virtualdatabase.xml.loadbalancer.raidb2ec_rr.failed");
02410       logger.error(msg, e);
02411       throw new SAXException(msg, e);
02412     }
02413   }
02414 
02415   /**
02416    * Sets {@link #currentLoadBalancer}as a new <code> RAIDb2ec_WRR</code>
02417    * using the parsed attributes.
02418    * 
02419    * @param atts parsed attributes
02420    * @exception SAXException if an error occurs
02421    */
02422   private void newRAIDb2ecWeightedRoundRobinLoadBalancer(Attributes atts)
02423       throws SAXException
02424   {
02425     if (currentWaitForCompletionPolicy == null)
02426       currentWaitForCompletionPolicy = new WaitForCompletionPolicy();
02427 
02428     if (logger.isDebugEnabled())
02429     {
02430       logger.debug(Translate
02431           .get("virtualdatabase.xml.loadbalancer.raidb2_wrr.set"));
02432       logger.debug(Translate.get(
02433           "virtualdatabase.xml.loadbalancer.waitforcompletion.rule",
02434           currentWaitForCompletionPolicy.getInformation()));
02435     }
02436 
02437     try
02438     {
02439       currentLoadBalancer = new RAIDb2ec_WRR(currentVirtualDatabase,
02440           currentWaitForCompletionPolicy, currentCreateTablePolicy,
02441           currentErrorCheckingPolicy, currentNbOfConcurrentReads);
02442       if (logger.isDebugEnabled())
02443         logger.debug(Translate.get(
02444             "virtualdatabase.xml.loadbalancer.errorchecking.policy",
02445             currentErrorCheckingPolicy.getInformation()));
02446     }
02447     catch (Exception e)
02448     {
02449       String msg = Translate
02450           .get("virtualdatabase.xml.loadbalancer.raidb2ec_wrr.failed");
02451       logger.error(msg, e);
02452       throw new SAXException(msg, e);
02453     }
02454   }
02455 
02456   //
02457   // Load balancer policies
02458   //
02459 
02460   /**
02461    * Set the WaitForCompletion policy.
02462    * 
02463    * @param atts parsed attributes
02464    * @exception SAXException if an error occurs
02465    */
02466   private void newWaitForCompletion(Attributes atts) throws SAXException
02467   {
02468     String policy = atts.getValue(DatabasesXmlTags.ATT_policy);
02469     currentWaitForCompletionPolicy = new WaitForCompletionPolicy();
02470 
02471     if (policy.equals(DatabasesXmlTags.VAL_first))
02472       currentWaitForCompletionPolicy.setPolicy(WaitForCompletionPolicy.FIRST);
02473     else if (policy.equals(DatabasesXmlTags.VAL_majority))
02474       currentWaitForCompletionPolicy
02475           .setPolicy(WaitForCompletionPolicy.MAJORITY);
02476     else if (policy.equals(DatabasesXmlTags.VAL_all))
02477       currentWaitForCompletionPolicy.setPolicy(WaitForCompletionPolicy.ALL);
02478     else
02479       throw new SAXException(Translate.get(
02480           "virtualdatabase.xml.loadbalancer.waitforcompletion.unsupported",
02481           policy));
02482   }
02483 
02484   /**
02485    * Add an ErrorChecking policy.
02486    * 
02487    * @param atts parsed attributes
02488    * @exception SAXException if an error occurs
02489    */
02490   private void newErrorChecking(Attributes atts) throws SAXException
02491   {
02492     String nbOfNodes = atts.getValue(DatabasesXmlTags.ATT_numberOfNodes);
02493     String policy = atts.getValue(DatabasesXmlTags.ATT_policy);
02494     if (policy.equals(DatabasesXmlTags.VAL_random))
02495       currentErrorCheckingPolicy = new ErrorCheckingRandom(Integer
02496           .parseInt(nbOfNodes));
02497     else if (policy.equals(DatabasesXmlTags.VAL_roundRobin))
02498       currentErrorCheckingPolicy = new ErrorCheckingRoundRobin(Integer
02499           .parseInt(nbOfNodes));
02500     else if (policy.equals(DatabasesXmlTags.VAL_all))
02501       currentErrorCheckingPolicy = new ErrorCheckingAll();
02502     else
02503       throw new SAXException(Translate.get(
02504           "virtualdatabase.xml.loadbalancer.errorchecking.unsupported", policy));
02505   }
02506 
02507   /**
02508    * Add a CreateTable rule.
02509    * 
02510    * @param atts parsed attributes
02511    * @exception SAXException if an error occurs
02512    */
02513   private void newCreateTable(Attributes atts) throws SAXException
02514   {
02515     String tableName = atts.getValue(DatabasesXmlTags.ATT_tableName);
02516     String nbOfNodes = atts.getValue(DatabasesXmlTags.ATT_numberOfNodes);
02517     String policy = atts.getValue(DatabasesXmlTags.ATT_policy);
02518     backendNameList = new ArrayList();
02519     if (policy.equals(DatabasesXmlTags.VAL_random))
02520       currentCreateTableRule = new CreateTableRandom(backendNameList);
02521     else if (policy.equals(DatabasesXmlTags.VAL_roundRobin))
02522       currentCreateTableRule = new CreateTableRoundRobin(backendNameList);
02523     else if (policy.equals(DatabasesXmlTags.VAL_all))
02524       currentCreateTableRule = new CreateTableAll(backendNameList);
02525     else
02526       throw new SAXException(Translate.get(
02527           "virtualdatabase.xml.create.table.unsupported", policy));
02528 
02529     currentCreateTableRule.setNumberOfNodes(Integer.parseInt(nbOfNodes));
02530     currentCreateTableRule.setTableName(tableName);
02531   }
02532 
02533   /**
02534    * Adds a backend name to the current backendNameList.
02535    * 
02536    * @param atts parsed attributes
02537    */
02538   private void newBackendName(Attributes atts)
02539   {
02540     String name = atts.getValue(DatabasesXmlTags.ATT_name);
02541     if (logger.isDebugEnabled())
02542       logger.debug(Translate
02543           .get("virtualdatabase.xml.backend.policy.add", name));
02544     backendNameList.add(name);
02545   }
02546 
02547   /**
02548    * Sets the weight of the {@link #currentLoadBalancer}using the parsed
02549    * attributes.
02550    * 
02551    * @param atts parsed attributes
02552    * @exception SAXException if an error occurs
02553    */
02554   private void newBackendWeight(Attributes atts) throws SAXException
02555   {
02556     String name = atts.getValue(DatabasesXmlTags.ATT_name);
02557     try
02558     {
02559       int weight = Integer.parseInt(atts.getValue(DatabasesXmlTags.ATT_weight));
02560 
02561       if (logger.isDebugEnabled())
02562         logger.debug(Translate.get("virtualdatabase.xml.backend.weigth.set",
02563             new String[]{String.valueOf(weight), name}));
02564 
02565       currentLoadBalancer.setWeight(name, weight);
02566     }
02567     catch (Exception e)
02568     {
02569       String msg = Translate.get("virtualdatabase.xml.backend.weigth.failed",
02570           name);
02571       logger.error(msg, e);
02572       throw new SAXException(msg, e);
02573     }
02574   }
02575 
02576   /* Log recovery */
02577 
02578   /**
02579    * Sets the currentRecoveryLog as new <code>JDBCRecoveryLog</code> using the
02580    * parsed attributes.
02581    * 
02582    * @param atts parsed attributes
02583    * @exception SAXException if an error occurs
02584    */
02585   private void newJDBCRecoveryLog(Attributes atts) throws SAXException
02586   {
02587     try
02588     {
02589       String driverClassName = atts.getValue(DatabasesXmlTags.ATT_driver);
02590       String driverPath = atts.getValue(DatabasesXmlTags.ATT_driverPath);
02591       String url = atts.getValue(DatabasesXmlTags.ATT_url);
02592       String login = atts.getValue(DatabasesXmlTags.ATT_login);
02593       String password = atts.getValue(DatabasesXmlTags.ATT_password);
02594       String timeout = atts.getValue(DatabasesXmlTags.ATT_requestTimeout);
02595       // Convert to ms
02596       requestTimeout = Integer.parseInt(timeout) * 1000;
02597 
02598       if (logger.isDebugEnabled())
02599         logger.debug(Translate.get(
02600             "virtualdatabase.xml.recoverylog.jdbc.create", new String[]{
02601                 driverClassName, url, login, password,
02602                 String.valueOf(requestTimeout)}));
02603 
02604       currentRecoveryLog = new JDBCRecoveryLog(driverPath, driverClassName,
02605           url, login, password, requestTimeout);
02606       //currentRecoveryLog.setBackendTableCreateStatement();
02607     }
02608     catch (Exception e)
02609     {
02610       String msg = Translate.get("virtualdatabase.xml.recoverylog.jdbc.failed");
02611       logger.error(msg, e);
02612       throw new SAXException(msg, e);
02613     }
02614   }
02615 
02616   /**
02617    * Sets the recovery log table create statement for the current
02618    * <code>JDBCRecoveryLog</code> using the <code>RecoveryLogTable</code>
02619    * parsed attributes.
02620    * 
02621    * @param atts parsed attributes
02622    * @exception SAXException if an error occurs
02623    */
02624   private void newJDBCRecoveryLogTable(Attributes atts) throws SAXException
02625   {
02626     try
02627     {
02628       String tableName = atts.getValue(DatabasesXmlTags.ATT_tableName);
02629       String idType = atts.getValue(DatabasesXmlTags.ATT_idColumnType);
02630       String vloginType = atts.getValue(DatabasesXmlTags.ATT_vloginColumnType);
02631       String sqlName = atts.getValue(DatabasesXmlTags.ATT_sqlColumnName);
02632       String sqlType = atts.getValue(DatabasesXmlTags.ATT_sqlColumnType);
02633       String transactionIdType = atts
02634           .getValue(DatabasesXmlTags.ATT_transactionIdColumnType);
02635       String extraStatement = atts
02636           .getValue(DatabasesXmlTags.ATT_extraStatementDefinition);
02637 
02638       if (currentRecoveryLog == null)
02639       {
02640         String msg = Translate
02641             .get("virtualdatabase.xml.recoverylog.jdbc.recoverytable.setnull");
02642         logger.error(msg);
02643         throw new SAXException(msg);
02644       }
02645       else
02646         currentRecoveryLog.setLogTableCreateStatement(tableName, idType,
02647             vloginType, sqlName, sqlType, transactionIdType, extraStatement);
02648     }
02649     catch (Exception e)
02650     {
02651       String msg = Translate
02652           .get("virtualdatabase.xml.recoverylog.jdbc.recoverytable.failed");
02653       logger.error(msg, e);
02654       throw new SAXException(msg, e);
02655     }
02656   }
02657 
02658   /**
02659    * Sets the recovery log table create statement for the current
02660    * <code>JDBCRecoveryLog</code> using the <code>RecoveryLogTable</code>
02661    * parsed attributes.
02662    * 
02663    * @param atts parsed attributes
02664    * @exception SAXException if an error occurs
02665    */
02666   private void newJDBCRecoveryCheckpointTable(Attributes atts)
02667       throws SAXException
02668   {
02669     try
02670     {
02671       String tableName = atts.getValue(DatabasesXmlTags.ATT_tableName);
02672       String nameType = atts
02673           .getValue(DatabasesXmlTags.ATT_checkpointNameColumnType);
02674       String requestIdType = atts
02675           .getValue(DatabasesXmlTags.ATT_requestIdColumnType);
02676       String extraStatement = atts
02677           .getValue(DatabasesXmlTags.ATT_extraStatementDefinition);
02678 
02679       if (currentRecoveryLog == null)
02680       {
02681         String msg = Translate
02682             .get("virtualdatabase.xml.recoverylog.jdbc.checkpointtable.setnull");
02683         logger.error(msg);
02684         throw new SAXException(msg);
02685       }
02686       else
02687         currentRecoveryLog.setCheckpointTableCreateStatement(tableName,
02688             nameType, requestIdType, extraStatement);
02689     }
02690     catch (Exception e)
02691     {
02692       String msg = Translate
02693           .get("virtualdatabase.xml.recoverylog.jdbc.checkpointtable.failed");
02694       logger.error(msg, e);
02695       throw new SAXException(msg, e);
02696     }
02697   }
02698 
02699   /**
02700    * Sets the backend log table create statement for the current
02701    * <code>JDBCRecoveryLog</code> using the <code>BackendLogTable</code>
02702    * parsed attributes.
02703    * 
02704    * @param atts parsed attributes
02705    * @exception SAXException if an error occurs
02706    */
02707   private void newJDBCRecoveryBackendTable(Attributes atts) throws SAXException
02708   {
02709     try
02710     {
02711       String tableName = atts.getValue(DatabasesXmlTags.ATT_tableName);
02712       String checkpointNameType = atts
02713           .getValue(DatabasesXmlTags.ATT_checkpointNameColumnType);
02714       String databaseNameType = atts
02715           .getValue(DatabasesXmlTags.ATT_databaseNameColumnType);
02716       String backendNameType = atts
02717           .getValue(DatabasesXmlTags.ATT_backendNameColumnType);
02718       String backendStateType = atts
02719           .getValue(DatabasesXmlTags.ATT_backendStateColumnType);
02720       String extraStatement = atts
02721           .getValue(DatabasesXmlTags.ATT_extraStatementDefinition);
02722 
02723       if (currentRecoveryLog == null)
02724       {
02725         String msg = Translate
02726             .get("virtualdatabase.xml.recoverylog.jdbc.backendtable.setnull");
02727         logger.error(msg);
02728         throw new SAXException(msg);
02729       }
02730       else
02731         currentRecoveryLog.setBackendTableCreateStatement(tableName,
02732             checkpointNameType, backendNameType, backendStateType,
02733             databaseNameType, extraStatement);
02734     }
02735     catch (Exception e)
02736     {
02737       String msg = Translate
02738           .get("virtualdatabase.xml.recoverylog.jdbc.backendtable.failed");
02739       logger.error(msg, e);
02740       throw new SAXException(msg, e);
02741     }
02742   }
02743 
02744   /**
02745    * Sets the currentRecoveryLog as new <code>FileRecoveryLog</code> using the
02746    * parsed attributes.
02747    * 
02748    * @param atts parsed attributes
02749    * @exception SAXException if an error occurs
02750    */
02751   private void newFileRecoveryLog(Attributes atts) throws SAXException
02752   {
02753     String msg = "FileRecoveryLog is not yet implemented";
02754     logger.error(msg);
02755     throw new SAXException(msg);
02756   }
02757 
02758   /* Connection manager */
02759 
02760   /**
02761    * Sets the currentRecoveryLog as new <code>JDBCRecoveryLog</code> using the
02762    * parsed attributes.
02763    * 
02764    * @param atts parsed attributes
02765    * @exception SAXException if an error occurs
02766    */
02767   private void newConnectionManager(Attributes atts) throws SAXException
02768   {
02769     connectionManagerVLogin = atts.getValue(DatabasesXmlTags.ATT_vLogin);
02770     String connectionManagerRLogin = atts.getValue(DatabasesXmlTags.ATT_rLogin);
02771     String connectionManagerRPassword = atts
02772         .getValue(DatabasesXmlTags.ATT_rPassword);
02773     String backendName = currentBackend.getName();
02774 
02775     // Check that the virtual login has been defined
02776     if (!currentAuthenticationManager
02777         .isValidVirtualLogin(connectionManagerVLogin))
02778     {
02779       String msg = Translate.get(
02780           "virtualdatabase.xml.connectionmanager.vlogin.undefined",
02781           new String[]{connectionManagerVLogin, currentBackend.getName()});
02782       logger.error(msg);
02783       throw new SAXException(msg);
02784     }
02785     // Add Real user for the database
02786     currentDatabaseBackendUser = new DatabaseBackendUser(backendName,
02787         connectionManagerRLogin, connectionManagerRPassword);
02788 
02789     if (logger.isDebugEnabled())
02790       logger.debug(Translate
02791           .get("virtualdatabase.xml.authentication.login.real.add",
02792               new String[]{connectionManagerRLogin, connectionManagerRPassword,
02793                   backendName}));
02794 
02795     try
02796     {
02797       currentAuthenticationManager.addRealUser(connectionManagerVLogin,
02798           currentDatabaseBackendUser);
02799     }
02800     catch (AuthenticationManagerException e)
02801     {
02802       String msg = Translate
02803           .get("virtualdatabase.xml.authentication.login.real.add.failed");
02804       logger.error(msg, e);
02805       throw new SAXException(msg, e);
02806     }
02807 
02808     //    // Get database real user
02809     //    currentDatabaseBackendUser = currentAuthenticationManager
02810     //        .getDatabaseBackendUser(connectionManagerVLogin, currentBackend
02811     //            .getName());
02812     //
02813     //    if (currentDatabaseBackendUser == null)
02814     //    {
02815     //      String msg = Translate.get(
02816     //          "virtualdatabase.xml.connectionmanager.rlogin.undefined",
02817     //          new String[]{currentBackend.getName(), connectionManagerVLogin});
02818     //      logger.error(msg);
02819     //      throw new SAXException(msg);
02820     //    }
02821   }
02822 
02823   /**
02824    * Adds a new <code>SimpleConnectionManager</code> to
02825    * {@link #currentBackend}using the parsed attributes.
02826    * 
02827    * @param atts parsed attributes
02828    */
02829   private void newSimpleConnectionManager(Attributes atts)
02830   {
02831     if (logger.isDebugEnabled())
02832       logger.debug(Translate.get(
02833           "virtualdatabase.xml.connectionmanager.simple.add", new String[]{
02834               currentBackend.getName(), connectionManagerVLogin,
02835               currentDatabaseBackendUser.getLogin(),
02836               currentDatabaseBackendUser.getPassword()}));
02837 
02838     currentBackend.addConnectionManager(connectionManagerVLogin,
02839         new SimpleConnectionManager(currentBackend.getURL(), currentBackend
02840             .getName(), currentDatabaseBackendUser.getLogin(),
02841             currentDatabaseBackendUser.getPassword(), currentBackend
02842                 .getDriverPath(), currentBackend.getDriverClassName()));
02843   }
02844 
02845   /**
02846    * Adds a new <code>FailFastPoolConnectionManager</code> to
02847    * {@link #currentBackend}using the parsed attributes.
02848    * 
02849    * @param atts parsed attributes
02850    * @exception SAXException if an error occurs
02851    */
02852   private void newFailFastPoolConnectionManager(Attributes atts)
02853       throws SAXException
02854   {
02855     try
02856     {
02857       int poolSize = Integer.parseInt(atts
02858           .getValue(DatabasesXmlTags.ATT_poolSize));
02859 
02860       // sanity check
02861       if (poolSize < 1)
02862         throw new IllegalArgumentException(
02863             Translate
02864                 .get("virtualdatabase.xml.connectionmanager.failfast.failed.parameter"));
02865 
02866       if (logger.isDebugEnabled())
02867         logger.debug(Translate.get(
02868             "virtualdatabase.xml.connectionmanager.failfast.add", new String[]{
02869                 currentBackend.getName(), connectionManagerVLogin,
02870                 String.valueOf(poolSize),
02871                 currentDatabaseBackendUser.getLogin(),
02872                 currentDatabaseBackendUser.getPassword()}));
02873 
02874       currentBackend.addConnectionManager(connectionManagerVLogin,
02875           new FailFastPoolConnectionManager(currentBackend.getURL(),
02876               currentBackend.getName(), currentDatabaseBackendUser.getLogin(),
02877               currentDatabaseBackendUser.getPassword(), currentBackend
02878                   .getDriverPath(), currentBackend.getDriverClassName(),
02879               poolSize));
02880     }
02881     catch (Exception e)
02882     {
02883       String msg = Translate.get(
02884           "virtualdatabase.xml.connectionmanager.failfast.failed",
02885           currentBackend.getName());
02886       logger.error(msg, e);
02887       throw new SAXException(msg, e);
02888     }
02889   }
02890 
02891   /**
02892    * Adds a new <code>RandomWaitPoolConnectionManager</code> to
02893    * {@link #currentBackend}using the parsed attributes.
02894    * 
02895    * @param atts parsed attributes
02896    * @exception SAXException if an error occurs
02897    */
02898   private void newRandomWaitPoolConnectionManager(Attributes atts)
02899       throws SAXException
02900   {
02901     try
02902     {
02903       int poolSize = Integer.parseInt(atts
02904           .getValue(DatabasesXmlTags.ATT_poolSize));
02905       String timeoutString = atts.getValue(DatabasesXmlTags.ATT_timeout);
02906       int timeout = 0;
02907 
02908       if (timeoutString != null) // Timeout is IMPLIED and
02909         // may be null
02910         timeout = Integer.parseInt(timeoutString);
02911 
02912       // sanity check
02913       if (timeout < 0 || poolSize < 1)
02914         throw new IllegalArgumentException(
02915             Translate
02916                 .get("virtualdatabase.xml.connectionmanager.randomwait.failed.parameter"));
02917 
02918       if (logger.isDebugEnabled())
02919         logger.debug(Translate.get(
02920             "virtualdatabase.xml.connectionmanager.randomwait.add",
02921             new String[]{currentBackend.getName(), connectionManagerVLogin,
02922                 String.valueOf(poolSize), String.valueOf(timeout),
02923                 currentDatabaseBackendUser.getLogin(),
02924                 currentDatabaseBackendUser.getPassword()}));
02925 
02926       currentBackend.addConnectionManager(connectionManagerVLogin,
02927           new RandomWaitPoolConnectionManager(currentBackend.getURL(),
02928               currentBackend.getName(), currentDatabaseBackendUser.getLogin(),
02929               currentDatabaseBackendUser.getPassword(), currentBackend
02930                   .getDriverPath(), currentBackend.getDriverClassName(),
02931               poolSize, timeout));
02932     }
02933     catch (Exception e)
02934     {
02935       String msg = Translate.get(
02936           "virtualdatabase.xml.connectionmanager.randomwait.failed",
02937           currentBackend.getName());
02938       logger.error(msg, e);
02939       throw new SAXException(msg, e);
02940     }
02941   }
02942 
02943   /**
02944    * Adds a new <code>VariablePoolConnectionManager</code> to
02945    * {@link #currentBackend}using the parsed attributes.
02946    * 
02947    * @param atts parsed attributes
02948    * @exception SAXException if an error occurs
02949    */
02950   private void newVariablePoolConnectionManager(Attributes atts)
02951       throws SAXException
02952   {
02953     try
02954     {
02955       int initPoolSize = Integer.parseInt(atts
02956           .getValue(DatabasesXmlTags.ATT_initPoolSize));
02957 
02958       int minPoolSize = initPoolSize;
02959       // minPoolSize is IMPLIED and may be null
02960       String attr = atts.getValue(DatabasesXmlTags.ATT_minPoolSize);
02961       if (attr != null)
02962         minPoolSize = Integer.parseInt(attr);
02963 
02964       // maxPoolSize is IMPLIED and may be null
02965       int maxPoolSize = VariablePoolConnectionManager.DEFAULT_MAX_POOL_SIZE;
02966       attr = atts.getValue(DatabasesXmlTags.ATT_maxPoolSize);
02967       if (attr != null)
02968         maxPoolSize = Integer.parseInt(attr);
02969 
02970       String timeoutString = atts.getValue(DatabasesXmlTags.ATT_idleTimeout);
02971       int idleTimeout = VariablePoolConnectionManager.DEFAULT_IDLE_TIMEOUT;
02972       if (timeoutString != null) // idleTimeout is IMPLIED
02973         // and may be null
02974         idleTimeout = Integer.parseInt(timeoutString);
02975 
02976       timeoutString = atts.getValue(DatabasesXmlTags.ATT_waitTimeout);
02977       int waitTimeout = VariablePoolConnectionManager.DEFAULT_WAIT_TIMEOUT;
02978       if (timeoutString != null) // waitTimeout is IMPLIED
02979         // and may be null
02980         waitTimeout = Integer.parseInt(timeoutString);
02981 
02982       // sanity checks
02983       if (minPoolSize < 0 || maxPoolSize < 0
02984           || (maxPoolSize != 0 && minPoolSize > maxPoolSize)
02985           || (maxPoolSize != 0 && initPoolSize > maxPoolSize)
02986           || initPoolSize < minPoolSize)
02987         throw new IllegalArgumentException(
02988             Translate
02989                 .get("virtualdatabase.xml.connectionmanager.variable.failed.parameter"));
02990 
02991       if (logger.isDebugEnabled())
02992         logger.debug(Translate.get(
02993             "virtualdatabase.xml.connectionmanager.randomwait.add",
02994             new String[]{currentBackend.getName(), connectionManagerVLogin,
02995                 String.valueOf(initPoolSize), String.valueOf(minPoolSize),
02996                 String.valueOf(maxPoolSize), String.valueOf(idleTimeout),
02997                 String.valueOf(waitTimeout),
02998                 currentDatabaseBackendUser.getLogin(),
02999                 currentDatabaseBackendUser.getPassword()}));
03000 
03001       currentBackend
03002           .addConnectionManager(connectionManagerVLogin,
03003               new VariablePoolConnectionManager(currentBackend.getURL(),
03004                   currentBackend.getName(), currentDatabaseBackendUser
03005                       .getLogin(), currentDatabaseBackendUser.getPassword(),
03006                   currentBackend.getDriverPath(), currentBackend
03007                       .getDriverClassName(), initPoolSize, minPoolSize,
03008                   maxPoolSize, idleTimeout, waitTimeout));
03009     }
03010     catch (Exception e)
03011     {
03012       String msg = Translate.get(
03013           "virtualdatabase.xml.connectionmanager.variable.failed",
03014           currentBackend.getName());
03015       logger.error(msg, e);
03016       throw new SAXException(msg, e);
03017     }
03018   }
03019 
03020   /* Database schema */
03021 
03022   /**
03023    * Sets {@link #currentTable}as a new <code> DatabaseTable</code> using the
03024    * parsed attributs.
03025    * 
03026    * @param atts parsed attributes
03027    * @exception SAXException if error occurs
03028    */
03029   private void newDatabaseTable(Attributes atts) throws SAXException
03030   {
03031     String tableName = atts.getValue(DatabasesXmlTags.ATT_tableName);
03032     String nbOfColumns = atts.getValue(DatabasesXmlTags.ATT_nbOfColumns);
03033 
03034     if (logger.isDebugEnabled())
03035       logger.debug(Translate.get("virtualdatabase.xml.schema.table.add",
03036           new String[]{tableName, String.valueOf(nbOfColumns)}));
03037 
03038     numberOfColumns = Integer.parseInt(nbOfColumns);
03039 
03040     try
03041     {
03042       currentTable = new DatabaseTable(tableName, numberOfColumns);
03043     }
03044     catch (NumberFormatException e)
03045     {
03046       String msg = Translate.get("virtualdatabase.xml.schema.table.failed",
03047           tableName);
03048       logger.error(msg, e);
03049       throw new SAXException(msg, e);
03050     }
03051   }
03052 
03053   private void newDatabaseSchema(Attributes atts)
03054   {
03055     String dynamicLevel = atts.getValue(DatabasesXmlTags.ATT_dynamicPrecision);
03056     String gatherSystemTable = atts
03057         .getValue(DatabasesXmlTags.ATT_gatherSystemTables);
03058     String schemaName = atts.getValue(DatabasesXmlTags.ATT_schemaName);
03059 
03060     if (dynamicLevel == null)
03061       dynamicLevel = DatabasesXmlTags.VAL_all;
03062     if (gatherSystemTable == null)
03063       gatherSystemTable = DatabasesXmlTags.VAL_false;
03064     currentBackend.setDynamicPrecision(DatabaseBackendSchemaConstants
03065         .getDynamicSchemaLevel(dynamicLevel), DatabasesXmlTags.VAL_true
03066         .equals(gatherSystemTable), schemaName);
03067   }
03068 
03069   /**
03070    * Adds to {@link #currentTable}a new <code> DatabaseColumn</code> using the
03071    * parsed attributes.
03072    * 
03073    * @param atts parsed attributes
03074    */
03075   private void newDatabaseColumn(Attributes atts)
03076   {
03077     String columnName = atts.getValue(DatabasesXmlTags.ATT_columnName);
03078     String isUnique = atts.getValue(DatabasesXmlTags.ATT_isUnique);
03079 
03080     if (logger.isDebugEnabled())
03081       logger.debug(Translate.get("virtualdatabase.xml.schema.column.add",
03082           new String[]{columnName, String.valueOf(isUnique)}));
03083 
03084     currentTable.addColumn(new DatabaseColumn(columnName, isUnique
03085         .equals(DatabasesXmlTags.VAL_true)));
03086   }
03087 
03088   private void newDatabaseProcedure(Attributes atts)
03089   {
03090     String procedureName = atts.getValue(DatabasesXmlTags.ATT_name);
03091     String returnType = atts.getValue(DatabasesXmlTags.ATT_returnType);
03092     if (logger.isDebugEnabled())
03093       logger.debug(Translate.get("virtualdatabase.xml.schema.procedure.add",
03094           new String[]{procedureName, returnType}));
03095 
03096     currentProcedure = new DatabaseProcedure(procedureName, "",
03097         DatabaseProcedure.getTypeFromString(returnType));
03098   }
03099 
03100   private void newDatabaseProcedureColumn(Attributes atts)
03101   {
03102     String paramName = atts.getValue(DatabasesXmlTags.ATT_name);
03103     String nullable = atts.getValue(DatabasesXmlTags.ATT_nullable);
03104     String type = atts.getValue(DatabasesXmlTags.ATT_paramType);
03105     if (logger.isDebugEnabled())
03106       logger.debug(Translate.get(
03107           "virtualdatabase.xml.schema.procedure.parameter.add", new String[]{
03108               paramName, nullable, type}));
03109     currentProcedure.addParameter(new DatabaseProcedureParameter(paramName,
03110         DatabaseProcedureParameter.getColumnTypeFromString(type),
03111         DatabaseProcedureParameter.getNullFromString(nullable)));
03112   }
03113 }

Generated on Mon Apr 11 22:01:31 2005 for C-JDBC by  doxygen 1.3.9.1