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

Octopus.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): Nicolas Modrzyk. 
00022  * Contributor(s): Emmanuel Cecchet.
00023  */
00024 
00025 package org.objectweb.cjdbc.controller.backup;
00026 
00027 import java.io.BufferedReader;
00028 import java.io.BufferedWriter;
00029 import java.io.File;
00030 import java.io.FileNotFoundException;
00031 import java.io.FileReader;
00032 import java.io.FileWriter;
00033 import java.io.IOException;
00034 import java.io.PrintStream;
00035 import java.util.ArrayList;
00036 import java.util.HashMap;
00037 import java.util.Hashtable;
00038 import java.util.Iterator;
00039 import java.util.Vector;
00040 
00041 import org.apache.log4j.Category;
00042 import org.apache.log4j.Priority;
00043 import org.objectweb.cjdbc.common.exceptions.BackupException;
00044 import org.objectweb.cjdbc.common.exceptions.OctopusException;
00045 import org.objectweb.cjdbc.common.i18n.Translate;
00046 import org.objectweb.cjdbc.common.jmx.notifications.CjdbcNotificationList;
00047 import org.objectweb.cjdbc.common.log.Trace;
00048 import org.objectweb.cjdbc.common.shared.BackendState;
00049 import org.objectweb.cjdbc.common.shared.BackupListener;
00050 import org.objectweb.cjdbc.common.sql.schema.DatabaseTable;
00051 import org.objectweb.cjdbc.common.util.LoggingOutputStream;
00052 import org.objectweb.cjdbc.common.util.ZipMe;
00053 import org.objectweb.cjdbc.controller.backend.DatabaseBackend;
00054 import org.objectweb.cjdbc.controller.connection.AbstractConnectionManager;
00055 import org.webdocwf.util.loader.Loader;
00056 import org.webdocwf.util.loader.generator.LoaderGenerator;
00057 
00058 /**
00059  * Octopus Hook Class. It has the necessary methods and fields to use octopus
00060  * simply.
00061  * 
00062  * @see org.objectweb.cjdbc.controller.backup.OctopusConstants
00063  * @author <a href="mailto:Nicolas.Modrzyk@inrialpes.fr">Nicolas Modrzyk </a>
00064  * @author <a href="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
00065  */
00066 public class Octopus extends Thread
00067 {
00068   private static final String OCTOPUS_INCLUDE_HREF  = "<include href=\"sql/";
00069   static Trace                logger;
00070 
00071   static
00072   {
00073     String cjdbcHome = System.getProperty("cjdbc.home");
00074     if (cjdbcHome != null)
00075       System.setProperty("OCTOPUS_HOME", cjdbcHome + File.separator + "lib"
00076           + File.separator + "octopus" + File.separator + "xml");
00077   }
00078   static final String         TYPE_CSV              = "csv";
00079   static final String         COPY_MODE             = "copy";
00080   static final String         OVERRIDE_MODE         = "sync";
00081   static final String         GENERATE_DOC          = "sql";
00082   static final String         OCTOPUS_LOG_FILE      = "octopusLog.txt";
00083   boolean                     cleanOctopus          = false;
00084   boolean                     zipOctopus            = true;
00085 
00086   static final int            ZIP_MODE_CREATE       = 0;
00087   static final int            ZIP_MODE_EXPAND       = 1;
00088 
00089   static final int            OCTOPUS_MODE_FROM_CSV = 0;
00090   static final int            OCTOPUS_MODE_TO_CSV   = 1;
00091 
00092   /** Mode for backup using octopus */
00093   public static final int     MODE_BACKUP           = 0;
00094   /** Mode for recovery using octopus */
00095   public static final int     MODE_RECOVERY         = 1;
00096 
00097   private DatabaseBackend     database;
00098 
00099   private String              user;
00100   private String              password;
00101   private String              dumpName;
00102   private String              octopusDir;
00103   private String              csvDir;
00104   private String              loaderJobXmlFile;
00105   private ArrayList           tables;
00106   private static PrintStream  stream;
00107 
00108   static String               mainDirectory         = ".." + File.separator
00109                                                         + "backup";
00110 
00111   private boolean             backupMode;
00112 
00113   private Exception           runException;
00114 
00115   private BackupListener      listener;
00116 
00117   /**
00118    * Instanciate hook to octopus
00119    * 
00120    * @param database backend to manipulate with octopus
00121    * @param dumpName to name files
00122    * @throws BackupException if fails
00123    */
00124   public Octopus(DatabaseBackend database, String dumpName)
00125       throws BackupException
00126   {
00127     logger = Trace.getLogger(this.getClass().getName());
00128     // Prepare references
00129     this.database = database;
00130     this.dumpName = dumpName;
00131     this.tables = null;
00132 
00133     // Retrieve information
00134     getUserLogin();
00135     setPaths();
00136   }
00137 
00138   /**
00139    * Creates a new <code>Octopus</code> object and sets the mode to use it as
00140    * a thread
00141    * 
00142    * @param database the <code>DatabaseBackend</code> object to process
00143    * @param dumpName the dumpName to use for name of backup
00144    * @param backupMode true if we should backup, false if we should restore
00145    * @throws BackupException if fails (not due to Octopus)
00146    */
00147   public Octopus(DatabaseBackend database, String dumpName, boolean backupMode)
00148       throws BackupException
00149   {
00150     this(database, dumpName);
00151     this.backupMode = backupMode;
00152   }
00153 
00154   /**
00155    * Use Octopus only for a set of tables
00156    * 
00157    * @param database backend to manipulate with octopus
00158    * @param dumpName to name files
00159    * @param tables on which we should use Octopus
00160    * @param backupMode true if we should backup, false if we should restore
00161    * @throws BackupException if fails
00162    */
00163   public Octopus(DatabaseBackend database, String dumpName, ArrayList tables,
00164       boolean backupMode) throws BackupException
00165   {
00166     this(database, dumpName, backupMode);
00167     this.tables = tables;
00168   }
00169 
00170   /**
00171    * Use Octopus only for a set of tables
00172    * 
00173    * @param database backend to manipulate with octopus
00174    * @param dumpName to name files
00175    * @param tables on which we should use Octopus
00176    * @throws BackupException if fails
00177    */
00178   public Octopus(DatabaseBackend database, String dumpName, ArrayList tables)
00179       throws BackupException
00180   {
00181     this(database, dumpName);
00182     this.tables = tables;
00183   }
00184 
00185   /**
00186    * Convert database to csv and zip the files
00187    * 
00188    * @throws BackupException if failure is not due to octopus
00189    * @throws OctopusException if failure is due to octopus
00190    */
00191   public void backup() throws BackupException, OctopusException
00192   {
00193     sanityCheck();
00194     prepareOctopus(OCTOPUS_MODE_TO_CSV);
00195     launchOctopus();
00196     if (zipOctopus)
00197       zipOctopus(ZIP_MODE_CREATE);
00198     if (cleanOctopus)
00199       cleanUp();
00200   }
00201 
00202   /**
00203    * Recover database from zipped csv the files
00204    * 
00205    * @throws BackupException if failure is not due to octopus
00206    * @throws OctopusException if failure is due to octopus
00207    */
00208   public void restore() throws BackupException, OctopusException
00209   {
00210     if (zipOctopus)
00211       zipOctopus(ZIP_MODE_EXPAND);
00212     prepareOctopus(OCTOPUS_MODE_FROM_CSV);
00213     setOctopusLoaderJob();
00214     launchOctopus();
00215     if (cleanOctopus)
00216       cleanUp();
00217   }
00218 
00219   /**
00220    * @see java.lang.Runnable#run()
00221    */
00222   public void run()
00223   {
00224     if (backupMode)
00225       try
00226       {
00227         database.setState(BackendState.BACKUPING);
00228         backup();
00229         database.notifyJmx(CjdbcNotificationList.VIRTUALDATABASE_NEW_DUMP_LIST);
00230         // Backend keeps its dumpName (it should have disabled with dumpName
00231         // prior this backup operation).
00232         database.setState(BackendState.DISABLED);
00233         if (listener != null)
00234           listener.success(database.getName());
00235       }
00236       catch (Exception e)
00237       {
00238         database.setState(BackendState.UNKNOWN);
00239         runException = e;
00240         if (listener != null)
00241           listener.failure(database.getName(), e);
00242       }
00243     else
00244     {
00245       try
00246       {
00247         database.setState(BackendState.RECOVERING);
00248         restore();
00249         // Set the dumpName corresponding to this database dump
00250         database.setLastKnownCheckpoint(dumpName);
00251         database.setState(BackendState.DISABLED);
00252         if (listener != null)
00253           listener.success(database.getName());
00254       }
00255       catch (Exception e1)
00256       {
00257         database.setState(BackendState.UNKNOWN);
00258         runException = e1;
00259         if (listener != null)
00260           listener.failure(database.getName(), e1);
00261       }
00262     }
00263 
00264     // Wake up everybody waiting on the listener
00265     if (listener != null)
00266     {
00267       synchronized (listener)
00268       {
00269         listener.notifyAll();
00270       }
00271     }
00272   }
00273 
00274   /**
00275    * Check if backup can be executed.
00276    * 
00277    * @throws BackupException if backend cannot be used for backup
00278    */
00279   public void sanityCheck() throws BackupException
00280   {
00281     boolean notEnabled = false, noPendingRequests = false;
00282     if (database.isReadEnabled() == false)
00283       notEnabled = true;
00284 
00285     Vector pending = database.getPendingRequests();
00286     int size = pending.size();
00287     noPendingRequests = (size == 0) ? true : false;
00288     if (logger.isDebugEnabled())
00289     {
00290       if (!noPendingRequests)
00291       {
00292         for (int i = 0; i < size; i++)
00293         {
00294           logger.debug("Pending:" + pending.get(i).toString());
00295         }
00296       }
00297       logger.debug("Pending Requests:" + database.getPendingRequests().size());
00298       logger.debug("Read enabled:" + database.isReadEnabled());
00299       logger.debug("Write enabled:" + database.isWriteEnabled());
00300     }
00301     if (!(notEnabled && noPendingRequests))
00302       throw new BackupException(Translate.get("backend.not.ready.for.backup"));
00303   }
00304 
00305   /**
00306    * Delete a directory by deleting all sub files
00307    * 
00308    * @param dir to delete
00309    * @return true if success, false otherwise
00310    */
00311   public boolean deleteDir(File dir)
00312   {
00313     if (dir.isDirectory())
00314     {
00315       String[] children = dir.list();
00316       for (int i = 0; i < children.length; i++)
00317       {
00318         boolean success = deleteDir(new File(dir, children[i]));
00319         if (!success)
00320         {
00321           return false;
00322         }
00323       }
00324     }
00325     // The directory is now empty so delete it
00326     return dir.delete();
00327   }
00328 
00329   final Hashtable getOctopusStrings(DatabaseBackend database)
00330       throws BackupException
00331   {
00332     Hashtable strings = new Hashtable(3);
00333     String type = getDbType(database.getURL());
00334     String octopusPrefixUrl = OctopusConstants.getUrlPrefix(type);
00335     String databaseUrl = database.getURL();
00336 
00337     strings.put("octopusType", OctopusConstants.getOctopusType(type));
00338     strings.put("octopusDriver", OctopusConstants.getOctopusDriver(type));
00339     strings.put("octopusUrl", databaseUrl.substring(octopusPrefixUrl.length()));
00340 
00341     return strings;
00342   }
00343 
00344   final void generateMetadata(String sourceType, String sourceUrl,
00345       String sourceDriver, String sourceUser, String sourcePassword,
00346       String targetType, String targetDriver, String targetUrl,
00347       String targetUser, String targetPassword, boolean backup)
00348       throws OctopusException
00349   {
00350     if (logger.isDebugEnabled())
00351       logger.debug("### Generating metadata ###");
00352     callOctopusLoader(sourceType, sourceUrl, sourceDriver, sourceUser,
00353         sourcePassword, targetType, targetDriver, targetUrl, targetUser,
00354         targetPassword, backup, true);
00355   }
00356 
00357   /**
00358    * Prepare the loader job file for octopus
00359    */
00360   final void prepareOctopus(String sourceType, String sourceUrl,
00361       String sourceDriver, String sourceUser, String sourcePassword,
00362       String targetType, String targetDriver, String targetUrl,
00363       String targetUser, String targetPassword, boolean backup)
00364       throws OctopusException
00365   {
00366     if (logger.isDebugEnabled())
00367       logger.debug("### Generating loader job ###");
00368     callOctopusLoader(sourceType, sourceUrl, sourceDriver, sourceUser,
00369         sourcePassword, targetType, targetDriver, targetUrl, targetUser,
00370         targetPassword, backup, false);
00371   }
00372 
00373   /**
00374    * Generate all the metadata
00375    */
00376   final void callOctopusLoader(String sourceType, String sourceUrl,
00377       String sourceDriver, String sourceUser, String sourcePassword,
00378       String targetType, String targetDriver, String targetUrl,
00379       String targetUser, String targetPassword, boolean backup,
00380       boolean generateAllVendors) throws OctopusException
00381   {
00382     try
00383     {
00384       if (logger.isDebugEnabled())
00385       {
00386         logger.debug("Source Type:" + sourceType);
00387         logger.debug("Source Driver:" + sourceDriver);
00388         logger.debug("Source URL :" + sourceUrl);
00389         logger.debug("Source User :" + sourceUser);
00390         logger.debug("Target Type:" + targetType);
00391         logger.debug("Target Driver:" + targetDriver);
00392         logger.debug("Target URL:" + targetUrl);
00393         logger.debug("Target User :" + targetUser);
00394         if (backup)
00395           logger.debug("Backup Mode");
00396         else
00397           logger.debug("Restore Mode");
00398         logger.debug("Generate SQL for all vendors :" + generateAllVendors);
00399       }
00400       LoaderGenerator loader = new LoaderGenerator(sourceType, // sourceType
00401           sourceUrl, // sourceDatabase Url?
00402           COPY_MODE, // valueMode
00403           octopusDir, // generatorOutput
00404           sourceDriver, // sourceDriverName
00405           targetDriver, // TargetDriverName
00406           targetUrl, // targetDataBase
00407           targetType, // TargetType
00408           sourceUser, // sourceUser
00409           sourcePassword, // sourcePassword
00410           targetUser, // targetUser
00411           targetPassword, //targetPassword
00412           "", // domlPath
00413           "org.webdoc.util.loader", // package name
00414           "true", // generate drop table stmt
00415           "true", // generate drop integrity statement
00416           "true", // generate create table stmt
00417           "true", // generate create pk statement
00418           "true", // generate create fk statement
00419           "true", // generate create index stmt
00420           String.valueOf(generateAllVendors), // generate
00421           // sql
00422           // for
00423           // all
00424           // vendors
00425           String.valueOf(!generateAllVendors), // generate
00426           // xml
00427           "false", // generate doml
00428           String.valueOf(!generateAllVendors), // full
00429           // mode
00430           // ??
00431           String.valueOf(!backup), // restore mode
00432           null, //convertTablesToSemicolonSeparatedList(database.getTables()),
00433           // // tables list
00434           null // Jar file structure
00435       );
00436       loader.generate();
00437     }
00438     catch (Exception e)
00439     {
00440       throw new OctopusException(e);
00441     }
00442   }
00443 
00444   private String[] convertTablesToArray(ArrayList tablesList)
00445   {
00446     int length = tablesList.size();
00447     String[] result = new String[length];
00448     for (int i = 0; i < length; i++)
00449       result[i] = ((DatabaseTable) tablesList.get(i)).getName();
00450     return result;
00451   }
00452 
00453   /**
00454    * Returns the cleanOctopus value.
00455    * 
00456    * @return Returns the cleanOctopus.
00457    */
00458   public boolean isCleanOctopus()
00459   {
00460     return cleanOctopus;
00461   }
00462 
00463   /**
00464    * Returns the zipOctopus value.
00465    * 
00466    * @return Returns the zipOctopus.
00467    */
00468   public boolean isZipOctopus()
00469   {
00470     return zipOctopus;
00471   }
00472 
00473   /**
00474    * Retrieve the path for the octopus directory
00475    * 
00476    * @return string
00477    */
00478   public final String getOctopusDirectory()
00479   {
00480     return mainDirectory;
00481   }
00482 
00483   /**
00484    * Returns the runException value.
00485    * 
00486    * @return Returns the runException.
00487    */
00488   public Exception getRunException()
00489   {
00490     return runException;
00491   }
00492 
00493   /**
00494    * Set the default path of octopus directory to a new one
00495    * 
00496    * @param path of the directory
00497    */
00498   public final void setOctopusDirectory(String path)
00499   {
00500     mainDirectory = path;
00501   }
00502 
00503   /**
00504    * When used as a thread Octopus needs to know if this will be a backup or
00505    * restore operation.
00506    * 
00507    * @param mode Octopus.MODE_BACKUP for a backup or Octopus.MODE_RECOVERY for a
00508    *          recovery
00509    */
00510   public void setOctopusMode(int mode)
00511   {
00512     switch (mode)
00513     {
00514       case MODE_BACKUP :
00515         this.backupMode = true;
00516         break;
00517       case MODE_RECOVERY :
00518         this.backupMode = false;
00519         break;
00520       default :
00521         throw new RuntimeException("Invalid mode " + mode
00522             + " in setOctopusMode");
00523     }
00524   }
00525 
00526   /**
00527    * Sets the cleanOctopus value.
00528    * 
00529    * @param cleanOctopus The cleanOctopus to set.
00530    */
00531   public void setCleanOctopus(boolean cleanOctopus)
00532   {
00533     this.cleanOctopus = cleanOctopus;
00534   }
00535 
00536   /**
00537    * Set the callback listener of this octopus process
00538    * 
00539    * @param listener this thread will call the callback method on this object
00540    */
00541   public void setListener(BackupListener listener)
00542   {
00543     this.listener = listener;
00544   }
00545 
00546   /**
00547    * Sets the zipOctopus value.
00548    * 
00549    * @param zipOctopus The zipOctopus to set.
00550    */
00551   public void setZipOctopus(boolean zipOctopus)
00552   {
00553     this.zipOctopus = zipOctopus;
00554   }
00555 
00556   private void cleanUp()
00557   {
00558     if (logger.isDebugEnabled())
00559       logger.debug("Cleaning up temporary backup files...");
00560     File toRemove = new File(octopusDir);
00561     deleteDir(toRemove);
00562   }
00563 
00564   private void getUserLogin()
00565   {
00566     //Retrieve user login and password to connect to database
00567     HashMap connectionManagers = database.getConnectionManagers();
00568     Iterator iter = connectionManagers.values().iterator();
00569     AbstractConnectionManager connectionManager = (AbstractConnectionManager) iter
00570         .next();
00571     user = connectionManager.getLogin();
00572     password = connectionManager.getPassword();
00573     if (logger.isDebugEnabled())
00574       logger.debug("User:" + user + ":Password:" + password);
00575   }
00576 
00577   private void setPaths() throws BackupException
00578   {
00579     // Change output stream
00580     if (stream == null)
00581       stream = new PrintStream(new LoggingOutputStream(Category
00582           .getInstance(this.getClass().getName()), Priority.DEBUG), true);
00583     //stream.close();
00584     System.setOut(stream);
00585 
00586     // Create main octopus directory
00587     octopusDir = mainDirectory + File.separator + dumpName;
00588 
00589     File octopusd = new File(octopusDir);
00590     octopusd.mkdirs();
00591     octopusd.mkdir();
00592 
00593     // Create Csv directory
00594     csvDir = "csv";
00595     File csvd = new File(octopusDir + File.separator + csvDir);
00596     csvDir = csvd.getAbsolutePath();
00597     csvd.mkdirs();
00598     csvd.mkdir();
00599 
00600     // Create LoaderFile name
00601     loaderJobXmlFile = octopusDir + File.separator + "LoaderJob.olj";
00602 
00603     if (logger.isDebugEnabled())
00604     {
00605       logger.debug("=======================================");
00606       logger.debug("Using the following Octopus settings:");
00607       logger.debug("OCTOPUS_DIR=" + octopusDir);
00608       logger.debug("CSV_DIR=" + csvDir);
00609       logger.debug("LOADER_JOB_XML_FILE=" + loaderJobXmlFile);
00610       logger.debug("cleanOctopus=" + cleanOctopus);
00611       logger.debug("zipOctopus=" + cleanOctopus);
00612       logger.debug("OCTOPUS_HOME:" + System.getProperty("OCTOPUS_HOME"));
00613       logger.debug("=======================================");
00614     }
00615 
00616     if (!octopusd.exists() || !csvd.exists())
00617     {
00618       throw new BackupException("backup.directory.cannot.be.created");
00619     }
00620   }
00621 
00622   private void setOctopusLoaderJob() throws OctopusException, BackupException
00623   {
00624     Hashtable options = getOctopusStrings(database);
00625     String sourceType = (String) options.get("octopusType");
00626     String onErrorContinueEqualFalse = "onErrorContinue=\"false\"";
00627     String onErrorContinueEqualTrue = "onErrorContinue=\"true\"";
00628     BufferedReader br = null;
00629     BufferedWriter bw = null;
00630 
00631     try
00632     {
00633       br = new BufferedReader(new FileReader(loaderJobXmlFile));
00634       String line = "";
00635       StringBuffer buffer = new StringBuffer();
00636 
00637       while ((line = br.readLine()) != null)
00638       {
00639         /* Give the metadata location */
00640         int idx = line.indexOf(OCTOPUS_INCLUDE_HREF);
00641         if (idx != -1)
00642         {
00643           idx += OCTOPUS_INCLUDE_HREF.length();
00644           // -4 = Skip "sql/"
00645           line = line.substring(0, idx - 4) + ".." + File.separator
00646               + octopusDir + File.separator + "SQLForAllVendors"
00647               + File.separator + sourceType + File.separator + "sql"
00648               + File.separator + line.substring(idx);
00649         }
00650 
00651         /* Force on error continue */
00652         int index7 = line.indexOf(onErrorContinueEqualFalse);
00653         if (index7 != -1)
00654         {
00655           line = line.substring(0, index7) + onErrorContinueEqualTrue
00656               + line.substring(index7 + onErrorContinueEqualFalse.length());
00657         }
00658         buffer.append(line + System.getProperty("line.separator"));
00659       }
00660       br.close();
00661       if (logger.isDebugEnabled())
00662       {
00663         logger.debug("Octopus file updated with success");
00664       }
00665 
00666       bw = new BufferedWriter(new FileWriter(loaderJobXmlFile));
00667       bw.write(buffer.toString());
00668       bw.close();
00669     }
00670     catch (FileNotFoundException fie)
00671     {
00672       // loader job was not generated properly
00673       logger.warn(Translate.get("controller.octopus.loader.job.not.found"));
00674       throw new OctopusException(fie.getMessage());
00675     }
00676     catch (IOException e)
00677     {
00678       // Error while reading file
00679       logger.warn(Translate.get("controller.octopus.loader.io.problem"));
00680     }
00681     finally
00682     {
00683       // close the open streams
00684       if (bw != null)
00685         try
00686         {
00687           bw.close();
00688         }
00689         catch (IOException e1)
00690         {
00691 
00692         }
00693       if (br != null)
00694         try
00695         {
00696           br.close();
00697         }
00698         catch (IOException e2)
00699         {
00700         }
00701     }
00702   }
00703 
00704   /**
00705    * This start octopus with previously generated LoaderJob file
00706    * 
00707    * @throws OctopusException if octopus fails
00708    */
00709   private void launchOctopus() throws OctopusException
00710   {
00711     try
00712     {
00713       Loader myOctopus;
00714       if (tables == null)
00715       {
00716         // Copy everything
00717         myOctopus = new Loader(loaderJobXmlFile, Loader.LOGMODE_NORMAL,
00718             "cjdbc", octopusDir, OCTOPUS_LOG_FILE, true, null, null, true,
00719             null, 0, 100);
00720       }
00721       else
00722       {
00723         // Copy only the tables we want
00724         myOctopus = new Loader(loaderJobXmlFile, Loader.LOGMODE_NORMAL,
00725             "cjdbc", octopusDir, OCTOPUS_LOG_FILE, true, null, null, true,
00726             null, 0, 100, this.convertTablesToArray(tables));
00727 
00728       }
00729       try
00730       {
00731         myOctopus.load();
00732       }
00733       catch (Exception e)
00734       {
00735         logger.error("Failed to load octopus", e);
00736         throw new OctopusException(Translate.get(
00737             "controller.octopus.load.failed", e));
00738       }
00739     }
00740     // I am doing this because Octopus throws NullPointerException
00741     // all the time so it is impossible to know which failed
00742     catch (OctopusException oe)
00743     {
00744       // This is thrown only by the above.
00745       throw oe;
00746     }
00747     catch (Exception e)
00748     {
00749       throw new OctopusException(Translate
00750           .get("controller.octopus.instance.failed"));
00751     }
00752   }
00753 
00754   private void zipOctopus(int zipMode) throws BackupException
00755   {
00756     try
00757     {
00758       if (logger.isDebugEnabled())
00759       {
00760         logger.debug("Checkpoint:" + dumpName);
00761         logger.debug("CsvDir:" + csvDir);
00762         logger.debug("MainDir:" + mainDirectory);
00763       }
00764       switch (zipMode)
00765       {
00766         case ZIP_MODE_CREATE :
00767           new ZipMe().create(dumpName, octopusDir, mainDirectory);
00768           break;
00769         case ZIP_MODE_EXPAND :
00770           new ZipMe().expand(dumpName, ".", mainDirectory);
00771           break;
00772         default :
00773           throw new BackupException("invalid.zip.mode");
00774       }
00775     }
00776     catch (Exception e)
00777     {
00778       logger.error(e.getMessage(), e);
00779       throw new BackupException(e.getMessage());
00780     }
00781   }
00782 
00783   private String getDbType(String url) throws BackupException
00784   {
00785     if (url == null)
00786       throw new BackupException("Invalid null source url");
00787     int index = url.indexOf(':');
00788     int index2 = url.indexOf(':', index + 1);
00789     if (index == -1 || index2 == -1 || index > index2)
00790       throw new BackupException("Invalid source url format");
00791     String type = url.substring(index + 1, index2);
00792     return type;
00793   }
00794 
00795   private void prepareOctopus(int octopusMode) throws BackupException,
00796       OctopusException
00797   {
00798     // Declare variables
00799     String sourceType = "";
00800     String sourceUrl = "";
00801     String sourceDriver = "";
00802     String sourceUser = "";
00803     String sourcePassword = "";
00804 
00805     String targetType = "";
00806     String targetDriver = "";
00807     String targetUrl = "";
00808     String targetUser = "";
00809     String targetPassword = "";
00810 
00811     boolean backupMode = true;
00812 
00813     Hashtable options = getOctopusStrings(database);
00814 
00815     // Prepare Variables
00816     switch (octopusMode)
00817     {
00818       case OCTOPUS_MODE_FROM_CSV :
00819         targetType = (String) options.get("octopusType");
00820         targetUrl = (String) options.get("octopusUrl");
00821         targetDriver = (String) options.get("octopusDriver");
00822         targetUser = user;
00823         targetPassword = password;
00824         sourceType = OctopusConstants.getOctopusType(TYPE_CSV);
00825         sourceDriver = OctopusConstants.getOctopusDriver(TYPE_CSV);
00826         sourceUrl = csvDir;
00827         sourceUser = "";
00828         sourcePassword = "";
00829         backupMode = false;
00830         break;
00831       case OCTOPUS_MODE_TO_CSV :
00832         sourceType = (String) options.get("octopusType");
00833         sourceUrl = (String) options.get("octopusUrl");
00834         sourceDriver = (String) options.get("octopusDriver");
00835         sourceUser = user;
00836         sourcePassword = password;
00837         targetType = OctopusConstants.getOctopusType(TYPE_CSV);
00838         targetDriver = OctopusConstants.getOctopusDriver(TYPE_CSV);
00839         targetUrl = csvDir;
00840         targetUser = "";
00841         targetPassword = "";
00842         backupMode = true;
00843         // Generate metadata
00844         generateMetadata(sourceType, sourceUrl, sourceDriver, sourceUser,
00845             sourcePassword, targetType, targetDriver, targetUrl, targetUser,
00846             targetPassword, backupMode);
00847         break;
00848       default :
00849         throw new BackupException("invalid.octopus.prepare.type");
00850     }
00851 
00852     // Generate loader job
00853     prepareOctopus(sourceType, sourceUrl, sourceDriver, sourceUser,
00854         sourcePassword, targetType, targetDriver, targetUrl, targetUser,
00855         targetPassword, backupMode);
00856 
00857   }
00858 
00859 }

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