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