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    }