View Javadoc
1 package org.apache.torque.task; 2 3 /* ==================================================================== 4 * The Apache Software License, Version 1.1 5 * 6 * Copyright (c) 2001 The Apache Software Foundation. All rights 7 * reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. The end-user documentation included with the redistribution, 22 * if any, must include the following acknowledgment: 23 * "This product includes software developed by the 24 * Apache Software Foundation (http://www.apache.org/)." 25 * Alternately, this acknowledgment may appear in the software itself, 26 * if and wherever such third-party acknowledgments normally appear. 27 * 28 * 4. The names "Apache" and "Apache Software Foundation" and 29 * "Apache Turbine" must not be used to endorse or promote products 30 * derived from this software without prior written permission. For 31 * written permission, please contact apache@apache.org. 32 * 33 * 5. Products derived from this software may not be called "Apache", 34 * "Apache Turbine", nor may "Apache" appear in their name, without 35 * prior written permission of the Apache Software Foundation. 36 * 37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 * ==================================================================== 50 * 51 * This software consists of voluntary contributions made by many 52 * individuals on behalf of the Apache Software Foundation. For more 53 * information on the Apache Software Foundation, please see 54 * <http://www.apache.org/>. 55 */ 56 57 import java.io.File; 58 59 import java.util.ArrayList; 60 import java.util.Hashtable; 61 import java.util.Iterator; 62 import java.util.List; 63 64 import org.apache.commons.lang.StringUtils; 65 66 import org.apache.tools.ant.BuildException; 67 import org.apache.tools.ant.DirectoryScanner; 68 import org.apache.tools.ant.types.FileSet; 69 70 import org.apache.torque.engine.EngineException; 71 import org.apache.torque.engine.database.model.AppData; 72 import org.apache.torque.engine.database.model.Database; 73 import org.apache.torque.engine.database.transform.XmlToAppData; 74 75 import org.apache.velocity.VelocityContext; 76 import org.apache.velocity.context.Context; 77 import org.apache.velocity.texen.ant.TexenTask; 78 79 /*** 80 * A base torque task that uses either a single XML schema 81 * representing a data model, or a <fileset> of XML schemas. 82 * We are making the assumption that an XML schema representing 83 * a data model contains tables for a <strong>single</strong> 84 * database. 85 * 86 * @author <a href="mailto:jvanzyl@zenplex.com">Jason van Zyl</a> 87 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a> 88 */ 89 public class TorqueDataModelTask extends TexenTask 90 { 91 /*** 92 * XML that describes the database model, this is transformed 93 * into the application model object. 94 */ 95 protected String xmlFile; 96 97 /*** 98 * Fileset of XML schemas which represent our data models. 99 */ 100 protected List filesets = new ArrayList(); 101 102 /*** 103 * Data models that we collect. One from each XML schema file. 104 */ 105 protected List dataModels = new ArrayList(); 106 107 /*** 108 * Velocity context which exposes our objects 109 * in the templates. 110 */ 111 protected Context context; 112 113 /*** 114 * Map of data model name to database name. 115 * Should probably stick to the convention 116 * of them being the same but I know right now 117 * in a lot of cases they won't be. 118 */ 119 protected Hashtable dataModelDbMap; 120 121 /*** 122 * Hashtable containing the names of all the databases 123 * in our collection of schemas. 124 */ 125 protected Hashtable databaseNames; 126 127 //!! This is probably a crappy idea having the sql file -> db map 128 // here. I can't remember why I put it here at the moment ... 129 // maybe I was going to map something else. It can probably 130 // move into the SQL task. 131 132 /*** 133 * Name of the properties file that maps an SQL file 134 * to a particular database. 135 */ 136 protected String sqldbmap; 137 138 /*** 139 * The path to properties file containing db idiosyncrasies is 140 * constructed by appending the "getTargetDatabase()/db.props 141 * to this path. 142 */ 143 private String basePathToDbProps; 144 145 /*** 146 * The target database(s) we are generating SQL 147 * for. Right now we can only deal with a single 148 * target, but we will support multiple targets 149 * soon. 150 */ 151 private String targetDatabase; 152 153 /*** 154 * Target Java package to place the generated files in. 155 */ 156 private String targetPackage; 157 158 159 /*** 160 * Set the sqldbmap. 161 * 162 * @param sqldbmap th db map 163 */ 164 public void setSqlDbMap(String sqldbmap) 165 { 166 //!! Make all these references files not strings. 167 this.sqldbmap = project.resolveFile(sqldbmap).toString(); 168 } 169 170 /*** 171 * Get the sqldbmap. 172 * 173 * @return String sqldbmap. 174 */ 175 public String getSqlDbMap() 176 { 177 return sqldbmap; 178 } 179 180 /*** 181 * Return the data models that have been 182 * processed. 183 * 184 * @return List data models 185 */ 186 public List getDataModels() 187 { 188 return dataModels; 189 } 190 191 /*** 192 * Return the data model to database name map. 193 * 194 * @return Hashtable data model name to database name map. 195 */ 196 public Hashtable getDataModelDbMap() 197 { 198 return dataModelDbMap; 199 } 200 201 /*** 202 * Get the xml schema describing the application model. 203 * 204 * @return String xml schema file. 205 */ 206 public String getXmlFile() 207 { 208 return xmlFile; 209 } 210 211 /*** 212 * Set the xml schema describing the application model. 213 * 214 * @param xmlFile The new XmlFile value 215 */ 216 public void setXmlFile(String xmlFile) 217 { 218 this.xmlFile = project.resolveFile(xmlFile).toString(); 219 } 220 221 /*** 222 * Adds a set of xml schema files (nested fileset attribute). 223 * 224 * @param set a Set of xml schema files 225 */ 226 public void addFileset(FileSet set) 227 { 228 filesets.add(set); 229 } 230 231 /*** 232 * Get the current target database. 233 * 234 * @return String target database(s) 235 */ 236 public String getTargetDatabase() 237 { 238 return targetDatabase; 239 } 240 241 /*** 242 * Set the current target database. (e.g. mysql, oracle, ..) 243 * 244 * @param v target database(s) 245 */ 246 public void setTargetDatabase(String v) 247 { 248 targetDatabase = v; 249 } 250 251 /*** 252 * Get the current target package. 253 * 254 * @return return target java package. 255 */ 256 public String getTargetPackage() 257 { 258 return targetPackage; 259 } 260 261 /*** 262 * Set the current target package. This is where generated java classes will 263 * live. 264 * 265 * @param v target java package. 266 */ 267 public void setTargetPackage(String v) 268 { 269 targetPackage = v; 270 } 271 272 /*** 273 * The path to properties file containing db idiosyncrasies is 274 * constructed by appending the "getTargetDatabase()/db.props to this path. 275 * 276 * @return basepath to db.props 277 */ 278 public String getBasePathToDbProps() 279 { 280 return basePathToDbProps; 281 } 282 283 /*** 284 * The path to properties file containing db idiosyncrasies is 285 * constructed by appending the "getTargetDatabase()/db.props 286 * to this path. 287 * 288 * @param v basepath to db.props 289 */ 290 public void setBasePathToDbProps(String v) 291 { 292 this.basePathToDbProps = v; 293 } 294 295 /*** 296 * Set up the initial context for generating the SQL from the XML schema. 297 * 298 * @return the context 299 * @throws Exception 300 */ 301 public Context initControlContext() throws Exception 302 { 303 XmlToAppData xmlParser; 304 305 if (xmlFile == null && filesets.isEmpty()) 306 { 307 throw new BuildException("You must specify an XML schema or " 308 + "fileset of XML schemas!"); 309 } 310 311 try 312 { 313 if (xmlFile != null) 314 { 315 // Transform the XML database schema into 316 // data model object. 317 xmlParser = new XmlToAppData(getTargetDatabase(), 318 getTargetPackage(), getBasePathToDbProps()); 319 AppData ad = xmlParser.parseFile(xmlFile); 320 ad.setName(grokName(xmlFile)); 321 dataModels.add(ad); 322 } 323 else 324 { 325 // Deal with the filesets. 326 for (int i = 0; i < filesets.size(); i++) 327 { 328 FileSet fs = (FileSet) filesets.get(i); 329 DirectoryScanner ds = fs.getDirectoryScanner(project); 330 File srcDir = fs.getDir(project); 331 332 String[] dataModelFiles = ds.getIncludedFiles(); 333 334 // Make a transaction for each file 335 for (int j = 0; j < dataModelFiles.length; j++) 336 { 337 File f = new File(srcDir, dataModelFiles[j]); 338 xmlParser = new XmlToAppData(getTargetDatabase(), 339 getTargetPackage(), 340 getBasePathToDbProps()); 341 AppData ad = xmlParser.parseFile(f.toString()); 342 ad.setName(grokName(f.toString())); 343 dataModels.add(ad); 344 } 345 } 346 } 347 348 Iterator i = dataModels.iterator(); 349 databaseNames = new Hashtable(); 350 dataModelDbMap = new Hashtable(); 351 352 // Different datamodels may state the same database 353 // names, we just want the unique names of databases. 354 while (i.hasNext()) 355 { 356 AppData ad = (AppData) i.next(); 357 Database database = ad.getDatabase(); 358 databaseNames.put(database.getName(), database.getName()); 359 dataModelDbMap.put(ad.getName(), database.getName()); 360 } 361 } 362 catch (EngineException ee) 363 { 364 throw new BuildException(ee); 365 } 366 367 context = new VelocityContext(); 368 369 // Place our set of data models into the context along 370 // with the names of the databases as a convenience for now. 371 context.put("dataModels", dataModels); 372 context.put("databaseNames", databaseNames); 373 context.put("targetDatabase", targetDatabase); 374 context.put("targetPackage", targetPackage); 375 376 return context; 377 } 378 379 /*** 380 * Gets a name to use for the application's data model. 381 * 382 * @param xmlFile The path to the XML file housing the data model. 383 * @return The name to use for the <code>AppData</code>. 384 */ 385 private String grokName(String xmlFile) 386 { 387 // This can't be set from the file name as it is an unreliable 388 // method of naming the descriptor. Not everyone uses the same 389 // method as I do in the TDK. jvz. 390 391 String name = "data-model"; 392 int i = xmlFile.lastIndexOf(System.getProperty("file.separator")); 393 if (i != -1) 394 { 395 // Creep forward to the start of the file name. 396 i++; 397 398 int j = xmlFile.lastIndexOf('.'); 399 if (i < j) 400 { 401 name = xmlFile.substring(i, j); 402 } 403 else 404 { 405 // Weirdo 406 name = xmlFile.substring(i); 407 } 408 } 409 return name; 410 } 411 412 /*** 413 * Override Texen's context properties to map the 414 * torque.xxx properties (including defaults set by the 415 * org/apache/torque/defaults.properties) to just xxx. 416 * 417 * <p> 418 * Also, move xxx.yyy properties to xxxYyy as Velocity 419 * doesn't like the xxx.yyy syntax. 420 * </p> 421 * 422 * @param file the file to read the properties from 423 */ 424 public void setContextProperties(String file) 425 { 426 super.setContextProperties(file); 427 428 // Map the torque.xxx elements from the env to the contextProperties 429 Hashtable env = super.getProject().getProperties(); 430 for (Iterator i = env.keySet().iterator(); i.hasNext();) 431 { 432 String key = (String) i.next(); 433 if (key.startsWith("torque.")) 434 { 435 String newKey = key.substring("torque.".length()); 436 int j = newKey.indexOf("."); 437 while (j != -1) 438 { 439 newKey = 440 newKey.substring(0, j) 441 + StringUtils.capitalise(newKey.substring(j + 1)); 442 j = newKey.indexOf("."); 443 } 444 445 contextProperties.setProperty(newKey, env.get(key)); 446 } 447 } 448 } 449 }

This page was automatically generated by Maven