001 /** 002 * Copyright 2004-2012 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.apache.torque.mojo; 017 018 import java.io.File; 019 import java.io.IOException; 020 import java.util.List; 021 022 import org.apache.commons.lang.StringUtils; 023 import org.apache.maven.plugin.MojoExecutionException; 024 import org.apache.tools.ant.types.FileSet; 025 import org.apache.torque.task.TorqueDataModelTask; 026 import org.apache.torque.util.JdbcConfigurer; 027 import org.apache.torque.util.SimpleScanner; 028 import org.kuali.core.db.torque.PropertyHandlingException; 029 import org.kuali.db.DatabaseType; 030 031 /** 032 * The base class for mojos that wrap DataModelTasks 033 */ 034 public abstract class DataModelTaskMojo extends TexenTaskMojo { 035 036 /** 037 * The Velocity context property for the target database 038 */ 039 public static final String TARGET_DATABASE_CONTEXT_PROPERTY = "targetDatabase"; 040 041 /** 042 * Database URL. 043 * 044 * @parameter expression="${url}" 045 */ 046 String url; 047 048 /** 049 * The suffix of the generated sql files. 050 */ 051 String suffix = ""; 052 053 protected File getCanonicalReportFile() throws MojoExecutionException { 054 try { 055 String filename = getOutputDir() + FS + getReportFile(); 056 File file = new File(filename); 057 return file.getCanonicalFile(); 058 } catch (IOException e) { 059 throw new MojoExecutionException("Error with report file", e); 060 } 061 } 062 063 protected FileSet getAntFileSet(File baseDir, String includes, String excludes) { 064 FileSet fileSet = new FileSet(); 065 fileSet.setDir(baseDir); 066 fileSet.setIncludes(includes); 067 fileSet.setExcludes(excludes); 068 return fileSet; 069 } 070 071 /** 072 * Validate that some essential configuration items are present 073 */ 074 protected void updateConfiguration() throws MojoExecutionException { 075 try { 076 // loadPropertiesToMojo(); 077 new JdbcConfigurer().updateConfiguration(this); 078 } catch (PropertyHandlingException e) { 079 throw new MojoExecutionException("Error handling properties", e); 080 } 081 } 082 083 protected String getInvalidTargetDatabaseMessage() { 084 StringBuffer sb = new StringBuffer(); 085 sb.append("\n\n"); 086 sb.append("Target database of '" + getTargetDatabase() + "' is invalid.\n\n"); 087 sb.append("Valid values are " + org.springframework.util.StringUtils.arrayToCommaDelimitedString(DatabaseType.values()) + ".\n\n"); 088 sb.append("Specify targetDatabase in the plugin configuration or as a system property.\n\n"); 089 sb.append("For example:\n-DtargetDatabase=oracle\n\n."); 090 return sb.toString(); 091 } 092 093 /** 094 * Validate that some essential configuration items are present 095 */ 096 protected void validateConfiguration() throws MojoExecutionException { 097 if (StringUtils.isEmpty(getTargetDatabase())) { 098 throw new MojoExecutionException(getInvalidTargetDatabaseMessage()); 099 } 100 101 try { 102 DatabaseType.valueOf(getTargetDatabase().toUpperCase()); 103 } catch (IllegalArgumentException e) { 104 throw new MojoExecutionException(getInvalidTargetDatabaseMessage()); 105 } 106 } 107 108 /** 109 * The path to the directory where the schema XML files are located 110 * 111 * @parameter expression="${schemaDir}" default-value="${basedir}/src/main/impex" 112 * @required 113 */ 114 private String schemaDir; 115 116 /** 117 * The schema files from that directory which should be included (ant-style notation). 118 * 119 * @parameter expression="${schemaIncludes}" default-value="${project.artifactId}.xml" 120 * @required 121 */ 122 private String schemaIncludes; 123 124 /** 125 * The schema files from that directory which should be excluded (ant-style notation). 126 */ 127 private String schemaExcludes; 128 129 /** 130 * The type of database we are targeting (eg oracle, mysql). This is optional if <code>url</code> is supplied as the 131 * database type will be automatically detected based on the <code>url</code>. If targetDatabase is explicitly 132 * supplied it will override the type selected by the automatic detection logic. 133 * 134 * @parameter expression="${targetDatabase}" 135 */ 136 private String targetDatabase; 137 138 /** 139 * The target package for the generated classes. 140 * 141 * @parameter expression="${targetPackage}" default-value="impex.generated" 142 */ 143 private String targetPackage; 144 145 /** 146 * The file containing the generation report, relative to <code>outputDir</code>. 147 * 148 * @required 149 */ 150 private String reportFile; 151 152 /** 153 * Determines if this task should run only if the schema has changed 154 * 155 * @parameter expression="${runOnlyOnSchemaChange}" default-value="true" 156 */ 157 private boolean runOnlyOnSchemaChange; 158 159 /** 160 * The path to the properties file containing the mapping sql file -> target database. 161 * 162 * @parameter expression="${sqlDbMap}" default-value="${project.build.directory}/reports/sqldbmap.properties" 163 */ 164 private String sqlDbMap; 165 166 /** 167 * Returns the path to the control template. 168 * 169 * @return the path to the control template. 170 */ 171 protected abstract String getControlTemplate(); 172 173 protected void addTargetDatabaseToOutputDir() { 174 TorqueDataModelTask task = (TorqueDataModelTask) super.getGeneratorTask(); 175 String newOutputDir = getOutputDir() + FS + getTargetDatabase(); 176 task.setOutputDirectory(new File(newOutputDir)); 177 setOutputDir(newOutputDir); 178 } 179 180 protected void addTargetDatabaseToReportFile() { 181 TorqueDataModelTask task = (TorqueDataModelTask) super.getGeneratorTask(); 182 String newReportFile = getReportFile() + "." + getTargetDatabase(); 183 task.setOutputFile(newReportFile); 184 setReportFile(newReportFile); 185 } 186 187 /** 188 * Configures the Texen task wrapped by this mojo 189 */ 190 protected void configureTask() throws MojoExecutionException { 191 super.configureTask(); 192 193 TorqueDataModelTask task = (TorqueDataModelTask) super.getGeneratorTask(); 194 task.setControlTemplate(getControlTemplate()); 195 task.setOutputFile(getReportFile()); 196 task.setTargetDatabase(getTargetDatabase()); 197 task.setTargetPackage(getTargetPackage()); 198 if (getSqlDbMap() != null) { 199 task.setSqlDbMap(getSqlDbMap()); 200 } 201 } 202 203 protected List<File> getSchemaFiles() { 204 return new SimpleScanner(new File(getSchemaDir()), getSchemaIncludes(), getSchemaExcludes()).getFiles(); 205 } 206 207 /** 208 * Returns the directory where the schema files are located. 209 * 210 * @return the the directory where the schema files are located. 211 */ 212 public String getSchemaDir() { 213 return schemaDir; 214 } 215 216 /** 217 * Sets the the directory where the schema files are located. 218 * 219 * @param schemaDir 220 * the directory where the schema files are located. 221 */ 222 public void setSchemaDir(String schemaDir) { 223 this.schemaDir = schemaDir; 224 } 225 226 /** 227 * Returns the target database (e.g. mysql, oracle, ... ) for the generated files. 228 * 229 * @return the target database for the generated files. 230 */ 231 public String getTargetDatabase() { 232 return targetDatabase; 233 } 234 235 /** 236 * Sets the target database (e.g. mysql, oracle, ... ) for the generated files. 237 * 238 * @param targetDatabase 239 * the target database for the generated files. 240 */ 241 public void setTargetDatabase(String targetDatabase) { 242 this.targetDatabase = targetDatabase; 243 } 244 245 /** 246 * Returns the target package for the generated classes. 247 * 248 * @return the target package for the generated classes. 249 */ 250 public String getTargetPackage() { 251 return targetPackage; 252 } 253 254 /** 255 * Sets the target package for the generated classes. 256 * 257 * param targetPackage the target package for the generated classes. 258 */ 259 public void setTargetPackage(String targetPackage) { 260 this.targetPackage = targetPackage; 261 } 262 263 /** 264 * Gets the path to the report file. The path is relative to <code>outputDir</code>. 265 * 266 * @return the path to the report file. 267 */ 268 public String getReportFile() { 269 return reportFile; 270 } 271 272 /** 273 * Sets the path to the report file. The path is relative to <code>outputDir</code>. 274 * 275 * @param reportFile 276 * the path to the report file. 277 */ 278 public void setReportFile(String reportFile) { 279 this.reportFile = reportFile; 280 } 281 282 /** 283 * Returns whether this mojo should be executed only if the schema has changed. 284 * 285 * @return true if the mojo only runs if the schema has changed, false otherwise. 286 */ 287 public boolean isRunOnlyOnSchemaChange() { 288 return runOnlyOnSchemaChange; 289 } 290 291 /** 292 * Sets whether this mojo should be executed only if the schema has changed. 293 * 294 * @param runOnlyOnSchemaChange 295 * whether the mojo only should run if the schema has changed. 296 */ 297 public void setRunOnlyOnSchemaChange(boolean runOnlyOnSchemaChange) { 298 this.runOnlyOnSchemaChange = runOnlyOnSchemaChange; 299 } 300 301 /** 302 * Returns the schema files which are excluded from generation. 303 * 304 * @return the pattern for the excluded files. 305 */ 306 public String getSchemaExcludes() { 307 return schemaExcludes; 308 } 309 310 /** 311 * Sets the schema files which are excluded from generation. 312 * 313 * @param schemaExcludes 314 * the pattern for the excluded files. 315 */ 316 public void setSchemaExcludes(String schemaExcludes) { 317 this.schemaExcludes = schemaExcludes; 318 } 319 320 /** 321 * Returns the schema files which are included in generation. 322 * 323 * @return the pattern for the included files. 324 */ 325 public String getSchemaIncludes() { 326 return schemaIncludes; 327 } 328 329 /** 330 * Sets the schema files which are included in generation. 331 * 332 * @param schemaIncludes 333 * the pattern for the included files. 334 */ 335 public void setSchemaIncludes(String schemaIncludes) { 336 this.schemaIncludes = schemaIncludes; 337 } 338 339 /** 340 * Returns the path to the mapping SQL Files -> database. 341 * 342 * @return the path to the mapping SQL Files -> database. 343 */ 344 public String getSqlDbMap() { 345 return sqlDbMap; 346 } 347 348 /** 349 * Sets the path to the mapping SQL Files -> database. 350 * 351 * @param sqlDbMap 352 * the absolute path to the mapping SQL Files -> database. 353 */ 354 public void setSqlDbMap(String sqlDbMap) { 355 this.sqlDbMap = sqlDbMap; 356 } 357 358 public String getUrl() { 359 return url; 360 } 361 362 public void setUrl(String url) { 363 this.url = url; 364 } 365 366 public String getSuffix() { 367 return suffix; 368 } 369 370 public void setSuffix(String suffix) { 371 this.suffix = suffix; 372 } 373 374 }