Coverage Report - org.apache.ojb.broker.ant.RepositoryDataTask
 
Classes in this File Line Coverage Branch Coverage Complexity
RepositoryDataTask
N/A
N/A
3.438
 
 1  
 package org.apache.ojb.broker.ant;
 2  
 
 3  
 /* Copyright 2005 The Apache Software Foundation
 4  
  *
 5  
  * Licensed under the Apache License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * You may obtain a copy of the License at
 8  
  *
 9  
  *     http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 
 18  
 import java.io.File;
 19  
 import java.io.FileInputStream;
 20  
 import java.util.ArrayList;
 21  
 import java.util.Iterator;
 22  
 import java.util.Properties;
 23  
 
 24  
 import org.apache.ddlutils.io.DatabaseIO;
 25  
 import org.apache.ddlutils.model.Database;
 26  
 import org.apache.ddlutils.task.DatabaseTaskBase;
 27  
 import org.apache.ojb.broker.PBKey;
 28  
 import org.apache.ojb.broker.metadata.DescriptorRepository;
 29  
 import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
 30  
 import org.apache.ojb.broker.metadata.MetadataManager;
 31  
 import org.apache.ojb.broker.metadata.RepositoryPersistor;
 32  
 import org.apache.tools.ant.AntClassLoader;
 33  
 import org.apache.tools.ant.BuildException;
 34  
 import org.apache.tools.ant.DirectoryScanner;
 35  
 import org.apache.tools.ant.Project;
 36  
 import org.apache.tools.ant.types.FileSet;
 37  
 
 38  
 /**
 39  
  * Task for inserting data XML that is defined in terms of the repository elements.
 40  
  * 
 41  
  * @author Thomas Dudziak
 42  
  */
 43  
 public class RepositoryDataTask extends DatabaseTaskBase
 44  
 {
 45  
     /** The sub tasks to execute. */
 46  
     private ArrayList _commands = new ArrayList();
 47  
     /** The alias of the jdbc connection to use (empty = default connection) */
 48  
     private String _jcdAlias;
 49  
     /** The properties file */
 50  
     private File _ojbPropertiesFile;
 51  
     /** The repository file */
 52  
     private File _repositoryFile;
 53  
     /** A single schema file to read. */
 54  
     private File _singleSchemaFile = null;
 55  
     /** The input files. */
 56  
     private ArrayList _fileSets = new ArrayList();
 57  
     /** Whether XML input files are validated against the internal or an external DTD. */
 58  
     private boolean _useInternalDtd = true;
 59  
 
 60  
 
 61  
     /**
 62  
      * Sets the alias of the jdbc connection to use.
 63  
      * 
 64  
      * @param alias The alias of the connection
 65  
      */
 66  
     public void setJcdAlias(String alias)
 67  
     {
 68  
         _jcdAlias = alias;
 69  
     }
 70  
 
 71  
     /**
 72  
      * Returns the alias of the jdbc connection.
 73  
      * 
 74  
      * @return The alias
 75  
      */
 76  
     public String getJcdAlias()
 77  
     {
 78  
         return _jcdAlias;
 79  
     }
 80  
 
 81  
     /**
 82  
      * Returns the ojb properties file, per default 'OJB.properties' in the current directory.
 83  
      * 
 84  
      * @return The ojb properties file
 85  
      */
 86  
     public File getOjbPropertiesFile()
 87  
     {
 88  
         return _ojbPropertiesFile;
 89  
     }
 90  
     /**
 91  
      * Sets the ojb properties file.
 92  
      *
 93  
      * @param ojbPropertiesFile The ojb properties file
 94  
      */
 95  
     public void setOjbPropertiesFile(File ojbPropertiesFile)
 96  
     {
 97  
         _ojbPropertiesFile = ojbPropertiesFile;
 98  
     }
 99  
 
 100  
     /**
 101  
      * Returns the repository file.
 102  
      * 
 103  
      * @return The repository file
 104  
      */
 105  
     public File getRepositoryFile()
 106  
     {
 107  
         return _repositoryFile;
 108  
     }
 109  
 
 110  
     /**
 111  
      * Sets the repository file (per default the one configured in the ojb properties file is used).
 112  
      * 
 113  
      * @param file The repository file
 114  
      */
 115  
     public void setRepositoryFile(File file)
 116  
     {
 117  
         _repositoryFile = file;
 118  
     }
 119  
 
 120  
     /**
 121  
      * Specifies whether XML schema files are validated against the internal or an external DTD.
 122  
      *
 123  
      * @param useInternalDtd <code>true</code> if input files are to be validated against the internal DTD
 124  
      */
 125  
     public void setUseInternalDtd(boolean useInternalDtd)
 126  
     {
 127  
         _useInternalDtd = useInternalDtd;
 128  
     }
 129  
 
 130  
     /**
 131  
      * Adds a fileset specifying the schema files.
 132  
      * 
 133  
      * @param fileset The additional input files
 134  
      */
 135  
     public void addConfiguredFileset(FileSet fileset)
 136  
     {
 137  
         _fileSets.add(fileset);
 138  
     }
 139  
 
 140  
     /**
 141  
      * Set the xml schema describing the application model.
 142  
      *
 143  
      * @param schemaFile The schema
 144  
      */
 145  
     public void setSchemaFile(File schemaFile)
 146  
     {
 147  
         _singleSchemaFile = schemaFile;
 148  
     }
 149  
 
 150  
     /**
 151  
      * Adds the "write dtd to file"-command.
 152  
      * 
 153  
      * @param command The command
 154  
      */
 155  
     public void addWriteDtdToFile(WriteDtdToFileCommand command)
 156  
     {
 157  
         _commands.add(command);
 158  
     }
 159  
 
 160  
     /**
 161  
      * Adds the "write data to database"-command.
 162  
      * 
 163  
      * @param command The command
 164  
      */
 165  
     public void addWriteDataToDatabase(WriteDataToDatabaseCommand command)
 166  
     {
 167  
         _commands.add(command);
 168  
     }
 169  
 
 170  
     /**
 171  
      * Adds the "write data sql to file"-command.
 172  
      * 
 173  
      * @param command The command
 174  
      */
 175  
     public void addWriteDataSqlToFile(WriteDataSqlToFileCommand command)
 176  
     {
 177  
         _commands.add(command);
 178  
     }
 179  
 
 180  
     /**
 181  
      * {@inheritDoc}
 182  
      */
 183  
     protected Database readModel()
 184  
     {
 185  
         DatabaseIO reader = new DatabaseIO();
 186  
         Database   model  = null;
 187  
 
 188  
         reader.setUseInternalDtd(_useInternalDtd);
 189  
         if ((_singleSchemaFile != null) && !_fileSets.isEmpty())
 190  
         {
 191  
             throw new BuildException("Please use either the schemafile attribute or the sub fileset element, but not both");
 192  
         }
 193  
         if (_singleSchemaFile != null)
 194  
         {
 195  
             model = readSingleSchemaFile(reader, _singleSchemaFile);
 196  
         }
 197  
         else
 198  
         {
 199  
             for (Iterator it = _fileSets.iterator(); it.hasNext();)
 200  
             {
 201  
                 FileSet          fileSet    = (FileSet)it.next();
 202  
                 File             fileSetDir = fileSet.getDir(getProject());
 203  
                 DirectoryScanner scanner    = fileSet.getDirectoryScanner(getProject());
 204  
                 String[]         files      = scanner.getIncludedFiles();
 205  
     
 206  
                 for (int idx = 0; (files != null) && (idx < files.length); idx++)
 207  
                 {
 208  
                     Database curModel = readSingleSchemaFile(reader, new File(fileSetDir, files[idx]));
 209  
     
 210  
                     if (model == null)
 211  
                     {
 212  
                         model = curModel;
 213  
                     }
 214  
                     else if (curModel != null)
 215  
                     {
 216  
                         try
 217  
                         {
 218  
                             model.mergeWith(curModel);
 219  
                         }
 220  
                         catch (IllegalArgumentException ex)
 221  
                         {
 222  
                             throw new BuildException("Could not merge with schema from file "+files[idx]+": "+ex.getLocalizedMessage(), ex);
 223  
                         }
 224  
                     }
 225  
                 }
 226  
             }
 227  
         }
 228  
         return model;
 229  
     }
 230  
 
 231  
     /**
 232  
      * Reads a single schema file.
 233  
      * 
 234  
      * @param reader     The schema reader 
 235  
      * @param schemaFile The schema file
 236  
      * @return The model
 237  
      */
 238  
     private Database readSingleSchemaFile(DatabaseIO reader, File schemaFile)
 239  
     {
 240  
         Database model = null;
 241  
 
 242  
         if (!schemaFile.isFile())
 243  
         {
 244  
             log("Path "+schemaFile.getAbsolutePath()+" does not denote a schema file", Project.MSG_ERR);
 245  
         }
 246  
         else if (!schemaFile.canRead())
 247  
         {
 248  
             log("Could not read schema file "+schemaFile.getAbsolutePath(), Project.MSG_ERR);
 249  
         }
 250  
         else
 251  
         {
 252  
             try
 253  
             {
 254  
                 model = reader.read(schemaFile);
 255  
                 log("Read schema file "+schemaFile.getAbsolutePath(), Project.MSG_INFO);
 256  
             }
 257  
             catch (Exception ex)
 258  
             {
 259  
                 throw new BuildException("Could not read schema file "+schemaFile.getAbsolutePath()+": "+ex.getLocalizedMessage(), ex);
 260  
             }
 261  
         }
 262  
         return model;
 263  
     }
 264  
 
 265  
     /**
 266  
      * Initializes OJB for the purposes of this task.
 267  
      * 
 268  
      * @return The metadata manager used by OJB
 269  
      */
 270  
     private MetadataManager initOJB()
 271  
     {
 272  
         try
 273  
         {
 274  
             if (_ojbPropertiesFile == null)
 275  
             {
 276  
                 _ojbPropertiesFile = new File("OJB.properties");
 277  
                 if (!_ojbPropertiesFile.exists())
 278  
                 {
 279  
                     throw new BuildException("Could not find OJB.properties, please specify it via the ojbpropertiesfile attribute");
 280  
                 }
 281  
             }
 282  
             else
 283  
             {
 284  
                 if (!_ojbPropertiesFile.exists())
 285  
                 {
 286  
                     throw new BuildException("Could not load the specified OJB properties file "+_ojbPropertiesFile);
 287  
                 }
 288  
                 log("Using properties file "+_ojbPropertiesFile.getAbsolutePath(), Project.MSG_INFO);
 289  
                 System.setProperty("OJB.properties", _ojbPropertiesFile.getAbsolutePath());
 290  
             }
 291  
 
 292  
             MetadataManager     metadataManager = MetadataManager.getInstance();
 293  
             RepositoryPersistor persistor       = new RepositoryPersistor();
 294  
 
 295  
             if (_repositoryFile != null)
 296  
             {
 297  
                 if (!_repositoryFile.exists())
 298  
                 {
 299  
                     throw new BuildException("Could not load the specified repository file "+_repositoryFile);
 300  
                 }
 301  
                 log("Loading repository file "+_repositoryFile.getAbsolutePath(), Project.MSG_INFO);
 302  
 
 303  
                 // this will load the info from the specified repository file
 304  
                 // and merge it with the existing info (if it has been loaded)
 305  
                 metadataManager.mergeConnectionRepository(persistor.readConnectionRepository(_repositoryFile.getAbsolutePath()));
 306  
                 metadataManager.mergeDescriptorRepository(persistor.readDescriptorRepository(_repositoryFile.getAbsolutePath()));
 307  
             }
 308  
             else if (metadataManager.connectionRepository().getAllDescriptor().isEmpty() &&
 309  
                      metadataManager.getGlobalRepository().getDescriptorTable().isEmpty())
 310  
             {
 311  
                 // Seems nothing was loaded, probably because we're not starting in the directory
 312  
                 // that the properties file is in, and the repository file path is relative
 313  
                 // So lets try to resolve this path and load the repository info manually
 314  
                 Properties props = new Properties();
 315  
 
 316  
                 props.load(new FileInputStream(_ojbPropertiesFile));
 317  
     
 318  
                 String repositoryPath = props.getProperty("repositoryFile", "repository.xml");
 319  
                 File   repositoryFile = new File(repositoryPath);
 320  
     
 321  
                 if (!repositoryFile.exists())
 322  
                 {
 323  
                     repositoryFile = new File(_ojbPropertiesFile.getParentFile(), repositoryPath);
 324  
                 }
 325  
                 metadataManager.mergeConnectionRepository(persistor.readConnectionRepository(repositoryFile.getAbsolutePath()));
 326  
                 metadataManager.mergeDescriptorRepository(persistor.readDescriptorRepository(repositoryFile.getAbsolutePath()));
 327  
             }
 328  
             // we might have to determine the default pb key ourselves
 329  
             if (metadataManager.getDefaultPBKey() == null)
 330  
             {
 331  
                 for (Iterator it = metadataManager.connectionRepository().getAllDescriptor().iterator(); it.hasNext();)
 332  
                 {
 333  
                     JdbcConnectionDescriptor descriptor = (JdbcConnectionDescriptor)it.next();
 334  
 
 335  
                     if (descriptor.isDefaultConnection())
 336  
                     {
 337  
                         metadataManager.setDefaultPBKey(new PBKey(descriptor.getJcdAlias(), descriptor.getUserName(), descriptor.getPassWord()));
 338  
                         break;
 339  
                     }
 340  
                 }
 341  
             }
 342  
             return metadataManager;
 343  
         }
 344  
         catch (Exception ex)
 345  
         {
 346  
             if (ex instanceof BuildException)
 347  
             {
 348  
                 throw (BuildException)ex;
 349  
             }
 350  
             else
 351  
             {
 352  
                 throw new BuildException(ex);
 353  
             }
 354  
         }
 355  
     }
 356  
 
 357  
     /**
 358  
      * {@inheritDoc}
 359  
      */
 360  
     public void execute() throws BuildException
 361  
     {
 362  
         if (_commands.isEmpty())
 363  
         {
 364  
             log("No sub tasks specified, so there is nothing to do.", Project.MSG_INFO);
 365  
             return;
 366  
         }
 367  
 
 368  
         ClassLoader    sysClassLoader = Thread.currentThread().getContextClassLoader();
 369  
         AntClassLoader newClassLoader = new AntClassLoader(getClass().getClassLoader(), true);
 370  
 
 371  
         // we're changing the thread classloader so that we can access resources
 372  
         // from the classpath used to load this task's class
 373  
         Thread.currentThread().setContextClassLoader(newClassLoader);
 374  
         
 375  
         try
 376  
         {
 377  
             MetadataManager      manager  = initOJB();
 378  
             Database             dbModel  = readModel();
 379  
             DescriptorRepository objModel = manager.getGlobalRepository();
 380  
 
 381  
             if (dbModel == null)
 382  
             {
 383  
                 throw new BuildException("No database model specified");
 384  
             }
 385  
             for (Iterator it = _commands.iterator(); it.hasNext();)
 386  
             {
 387  
                 Command cmd = (Command)it.next();
 388  
 
 389  
                 cmd.setPlatform(getPlatform());
 390  
                 cmd.execute(this, dbModel, objModel);
 391  
             }
 392  
         }
 393  
         finally
 394  
         {
 395  
             // rollback of our classloader change
 396  
             Thread.currentThread().setContextClassLoader(sysClassLoader);
 397  
         }
 398  
     }
 399  
 }