Coverage Report - org.apache.torque.task.TorqueDataModelTask
 
Classes in this File Line Coverage Branch Coverage Complexity
TorqueDataModelTask
0%
0/94
0%
0/24
1.762
 
 1  
 package org.apache.torque.task;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *   http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import java.io.File;
 23  
 import java.util.ArrayList;
 24  
 import java.util.Date;
 25  
 import java.util.Hashtable;
 26  
 import java.util.Iterator;
 27  
 import java.util.List;
 28  
 import java.util.Map;
 29  
 
 30  
 import org.apache.commons.lang.StringUtils;
 31  
 import org.apache.tools.ant.BuildException;
 32  
 import org.apache.tools.ant.DirectoryScanner;
 33  
 import org.apache.tools.ant.types.FileSet;
 34  
 import org.apache.torque.engine.EngineException;
 35  
 import org.apache.torque.engine.database.model.Database;
 36  
 import org.apache.velocity.VelocityContext;
 37  
 import org.apache.velocity.context.Context;
 38  
 import org.apache.texen.ant.TexenTask;
 39  
 import org.kuali.core.db.torque.DatabaseParser;
 40  
 import org.kuali.core.db.torque.KualiXmlToAppData;
 41  
 
 42  
 /**
 43  
  * A base torque task that uses either a single XML schema representing a data model, or a <fileset> of XML
 44  
  * schemas. We are making the assumption that an XML schema representing a data model contains tables for a
 45  
  * <strong>single</strong> database.
 46  
  * 
 47  
  * @author <a href="mailto:jvanzyl@zenplex.com">Jason van Zyl</a>
 48  
  * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
 49  
  */
 50  0
 public class TorqueDataModelTask extends TexenTask {
 51  
         /**
 52  
          * XML that describes the database model, this is transformed into the application model object.
 53  
          */
 54  
         protected String xmlFile;
 55  
 
 56  
         /** Fileset of XML schemas which represent our data models. */
 57  0
         protected List<FileSet> filesets = new ArrayList<FileSet>();
 58  
 
 59  
         /** Data models that we collect. One from each XML schema file. */
 60  0
         protected List<Database> dataModels = new ArrayList<Database>();
 61  
 
 62  
         /** Velocity context which exposes our objects in the templates. */
 63  
         protected Context context;
 64  
 
 65  
         /**
 66  
          * Map of data model name to database name. Should probably stick to the convention of them being the same but I
 67  
          * know right now in a lot of cases they won't be.
 68  
          */
 69  
         protected Hashtable<String, String> dataModelDbMap;
 70  
 
 71  
         /**
 72  
          * Hashtable containing the names of all the databases in our collection of schemas.
 73  
          */
 74  
         protected Hashtable<String, String> databaseNames;
 75  
 
 76  
         // !! This is probably a crappy idea having the sql file -> db map
 77  
         // here. I can't remember why I put it here at the moment ...
 78  
         // maybe I was going to map something else. It can probably
 79  
         // move into the SQL task.
 80  
 
 81  
         /**
 82  
          * Name of the properties file that maps an SQL file to a particular database.
 83  
          */
 84  
         protected String sqldbmap;
 85  
 
 86  
         /** The target database(s) we are generating SQL for. */
 87  
         private String targetDatabase;
 88  
 
 89  
         /** Target Java package to place the generated files in. */
 90  
         private String targetPackage;
 91  
 
 92  
         /**
 93  
          * Set the sqldbmap.
 94  
          * 
 95  
          * @param sqldbmap
 96  
          *            th db map
 97  
          */
 98  
         public void setSqlDbMap(String sqldbmap) {
 99  
                 // !! Make all these references files not strings.
 100  0
                 this.sqldbmap = getProject().resolveFile(sqldbmap).toString();
 101  0
         }
 102  
 
 103  
         /**
 104  
          * Get the sqldbmap.
 105  
          * 
 106  
          * @return String sqldbmap.
 107  
          */
 108  
         public String getSqlDbMap() {
 109  0
                 return sqldbmap;
 110  
         }
 111  
 
 112  
         /**
 113  
          * Return the data models that have been processed.
 114  
          * 
 115  
          * @return List data models
 116  
          */
 117  
         public List<Database> getDataModels() {
 118  0
                 return dataModels;
 119  
         }
 120  
 
 121  
         /**
 122  
          * Return the data model to database name map.
 123  
          * 
 124  
          * @return Hashtable data model name to database name map.
 125  
          */
 126  
         public Hashtable<String, String> getDataModelDbMap() {
 127  0
                 return dataModelDbMap;
 128  
         }
 129  
 
 130  
         /**
 131  
          * Get the xml schema describing the application model.
 132  
          * 
 133  
          * @return String xml schema file.
 134  
          */
 135  
         public String getXmlFile() {
 136  0
                 return xmlFile;
 137  
         }
 138  
 
 139  
         /**
 140  
          * Set the xml schema describing the application model.
 141  
          * 
 142  
          * @param xmlFile
 143  
          *            The new XmlFile value
 144  
          */
 145  
         public void setXmlFile(String xmlFile) {
 146  0
                 this.xmlFile = xmlFile;
 147  0
         }
 148  
 
 149  
         /**
 150  
          * Adds a set of xml schema files (nested fileset attribute).
 151  
          * 
 152  
          * @param set
 153  
          *            a Set of xml schema files
 154  
          */
 155  
         public void addFileset(FileSet set) {
 156  0
                 filesets.add(set);
 157  0
         }
 158  
 
 159  
         /**
 160  
          * Get the current target database.
 161  
          * 
 162  
          * @return String target database(s)
 163  
          */
 164  
         public String getTargetDatabase() {
 165  0
                 return targetDatabase;
 166  
         }
 167  
 
 168  
         /**
 169  
          * Set the current target database. (e.g. mysql, oracle, ..)
 170  
          */
 171  
         public void setTargetDatabase(String targetDatabase) {
 172  0
                 this.targetDatabase = targetDatabase;
 173  0
         }
 174  
 
 175  
         /**
 176  
          * Get the current target package.
 177  
          * 
 178  
          * @return return target java package.
 179  
          */
 180  
         public String getTargetPackage() {
 181  0
                 return targetPackage;
 182  
         }
 183  
 
 184  
         /**
 185  
          * Set the current target package. This is where generated java classes will live.
 186  
          */
 187  
         public void setTargetPackage(String targetPackage) {
 188  0
                 this.targetPackage = targetPackage;
 189  0
         }
 190  
 
 191  
         /**
 192  
          * Return a SAX parser that implements the DatabaseParser interface
 193  
          */
 194  
         protected DatabaseParser getDatabaseParser() {
 195  0
                 return new KualiXmlToAppData(getTargetDatabase(), getTargetPackage());
 196  
         }
 197  
 
 198  
         /**
 199  
          * Parse a schema XML File into a Database object
 200  
          */
 201  
         protected Database getDataModel(File file) throws EngineException {
 202  
                 // Get a handle to a parser
 203  0
                 DatabaseParser databaseParser = getDatabaseParser();
 204  
 
 205  
                 // Parse the file into a database
 206  0
                 Database database = databaseParser.parseResource(file.toString());
 207  
 
 208  
                 // Extract the filename
 209  0
                 database.setFileName(grokName(file.toString()));
 210  
 
 211  
                 // return the database
 212  0
                 return database;
 213  
         }
 214  
 
 215  
         /**
 216  
          * Get the list of schema XML files from our filesets
 217  
          */
 218  
         protected List<File> getDataModelFiles() {
 219  
                 // Allocate some storage
 220  0
                 List<File> dataModelFiles = new ArrayList<File>();
 221  
 
 222  
                 // Iterate through the filesets
 223  0
                 for (int i = 0; i < getFilesets().size(); i++) {
 224  
                         // Extract a fileset
 225  0
                         FileSet fs = getFilesets().get(i);
 226  
 
 227  
                         // Create a directory scanner
 228  0
                         DirectoryScanner ds = fs.getDirectoryScanner(getProject());
 229  
 
 230  
                         // Figure out the directory to scan
 231  0
                         File srcDir = fs.getDir(getProject());
 232  
 
 233  
                         // Scan the directory
 234  0
                         String[] dataModelFilesArray = ds.getIncludedFiles();
 235  
 
 236  
                         // Add each file in the directory to our list
 237  0
                         for (int j = 0; j < dataModelFilesArray.length; j++) {
 238  0
                                 File file = new File(srcDir, dataModelFilesArray[j]);
 239  0
                                 dataModelFiles.add(file);
 240  
                         }
 241  
                 }
 242  
 
 243  
                 // Return the list of schema.xml files
 244  0
                 return dataModelFiles;
 245  
         }
 246  
 
 247  
         /**
 248  
          * Parse schema XML files into Database objects
 249  
          */
 250  
         protected List<Database> getPopulatedDataModels() throws EngineException {
 251  
                 // Allocate some storage
 252  0
                 List<Database> databases = new ArrayList<Database>();
 253  
 
 254  
                 // Only one file to parse
 255  0
                 if (getXmlFile() != null) {
 256  
                         // Parse the file into a database object
 257  0
                         Database database = getDataModel(new File(getXmlFile()));
 258  
                         // Add it to our list
 259  0
                         databases.add(database);
 260  
                         // we are done
 261  0
                         return databases;
 262  
                 }
 263  
 
 264  
                 // Get the list of schema XML files to parse from our filesets
 265  0
                 List<File> dataModelFiles = getDataModelFiles();
 266  
                 // Iterate through the list, parsing each schema.xml file into a database object
 267  0
                 for (File dataModelFile : dataModelFiles) {
 268  
                         // Parse a schema.xml file into a database object
 269  0
                         Database database = getDataModel(dataModelFile);
 270  
                         // Add the database object to our list
 271  0
                         databases.add(database);
 272  0
                 }
 273  
                 // Return the list of database objects
 274  0
                 return databases;
 275  
         }
 276  
 
 277  
         /**
 278  
          * Set up the initial context for generating SQL
 279  
          * 
 280  
          * @return the context
 281  
          * @throws Exception
 282  
          */
 283  
         public Context initControlContext() throws Exception {
 284  0
                 if (xmlFile == null && filesets.isEmpty()) {
 285  0
                         throw new BuildException("You must specify an XML schema or fileset of XML schemas!");
 286  
                 }
 287  
 
 288  
                 try {
 289  0
                         dataModels = getPopulatedDataModels();
 290  0
                 } catch (EngineException ee) {
 291  0
                         throw new BuildException(ee);
 292  0
                 }
 293  
 
 294  0
                 Iterator<Database> i = dataModels.iterator();
 295  0
                 databaseNames = new Hashtable<String, String>();
 296  0
                 dataModelDbMap = new Hashtable<String, String>();
 297  
 
 298  
                 // Different datamodels may state the same database
 299  
                 // names, we just want the unique names of databases.
 300  0
                 while (i.hasNext()) {
 301  0
                         Database database = i.next();
 302  0
                         databaseNames.put(database.getName(), database.getName());
 303  0
                         dataModelDbMap.put(database.getFileName(), database.getName());
 304  0
                 }
 305  
 
 306  0
                 context = new VelocityContext();
 307  
 
 308  
                 // Place our set of data models into the context along
 309  
                 // with the names of the databases as a convenience for now.
 310  0
                 context.put("dataModels", dataModels);
 311  0
                 context.put("databaseNames", databaseNames);
 312  0
                 context.put("targetDatabase", targetDatabase);
 313  0
                 context.put("targetPackage", targetPackage);
 314  
 
 315  0
                 return context;
 316  
         }
 317  
 
 318  
         /**
 319  
          * Change type of "now" to java.util.Date
 320  
          * 
 321  
          * @see org.apache.velocity.texen.ant.TexenTask#populateInitialContext(org.apache.velocity.context.Context)
 322  
          */
 323  
         protected void populateInitialContext(Context context) throws Exception {
 324  0
                 super.populateInitialContext(context);
 325  0
                 context.put("now", new Date());
 326  0
         }
 327  
 
 328  
         /**
 329  
          * Gets a name to use for the application's data model.
 330  
          * 
 331  
          * @param xmlFile
 332  
          *            The path to the XML file housing the data model.
 333  
          * @return The name to use for the <code>AppData</code>.
 334  
          */
 335  
         private String grokName(String xmlFile) {
 336  
                 // This can't be set from the file name as it is an unreliable
 337  
                 // method of naming the descriptor. Not everyone uses the same
 338  
                 // method as I do in the TDK. jvz.
 339  
 
 340  0
                 String name = "data-model";
 341  0
                 int i = xmlFile.lastIndexOf(System.getProperty("file.separator"));
 342  0
                 if (i != -1) {
 343  
                         // Creep forward to the start of the file name.
 344  0
                         i++;
 345  
 
 346  0
                         int j = xmlFile.lastIndexOf('.');
 347  0
                         if (i < j) {
 348  0
                                 name = xmlFile.substring(i, j);
 349  
                         } else {
 350  
                                 // Weirdo
 351  0
                                 name = xmlFile.substring(i);
 352  
                         }
 353  
                 }
 354  0
                 return name;
 355  
         }
 356  
 
 357  
         /**
 358  
          * Override Texen's context properties to map the torque.xxx properties (including defaults set by the
 359  
          * org/apache/torque/defaults.properties) to just xxx.
 360  
          * 
 361  
          * <p>
 362  
          * Also, move xxx.yyy properties to xxxYyy as Velocity doesn't like the xxx.yyy syntax.
 363  
          * </p>
 364  
          * 
 365  
          * @param file
 366  
          *            the file to read the properties from
 367  
          */
 368  
         public void setContextProperties(String file) {
 369  0
                 super.setContextProperties(file);
 370  
 
 371  
                 // Map the torque.xxx elements from the env to the contextProperties
 372  0
                 Hashtable<?, ?> env = super.getProject().getProperties();
 373  0
                 for (Iterator<?> i = env.entrySet().iterator(); i.hasNext();) {
 374  0
                         Map.Entry<?, ?> entry = (Map.Entry<?, ?>) i.next();
 375  0
                         String key = (String) entry.getKey();
 376  0
                         if (key.startsWith("torque.")) {
 377  0
                                 String newKey = key.substring("torque.".length());
 378  0
                                 int j = newKey.indexOf(".");
 379  0
                                 while (j != -1) {
 380  0
                                         newKey = newKey.substring(0, j) + StringUtils.capitalize(newKey.substring(j + 1));
 381  0
                                         j = newKey.indexOf(".");
 382  
                                 }
 383  
 
 384  0
                                 contextProperties.setProperty(newKey, entry.getValue());
 385  
                         }
 386  0
                 }
 387  0
         }
 388  
 
 389  
         public List<FileSet> getFilesets() {
 390  0
                 return filesets;
 391  
         }
 392  
 
 393  
         public void setFilesets(List<FileSet> filesets) {
 394  0
                 this.filesets = filesets;
 395  0
         }
 396  
 }