001    package org.apache.torque.mojo;
002    
003    import java.io.File;
004    import java.util.List;
005    import java.util.Properties;
006    import java.util.Set;
007    import java.util.TreeSet;
008    
009    import org.apache.maven.plugin.MojoExecutionException;
010    import org.apache.maven.plugin.MojoFailureException;
011    import org.apache.tools.ant.DirectoryScanner;
012    import org.apache.torque.engine.database.model.Database;
013    import org.apache.torque.engine.database.model.Table;
014    import org.kuali.core.db.torque.SetUtils;
015    import org.kuali.core.db.torque.Utils;
016    
017    /**
018     * This mojo identifies data files that are present on the file system but are not present in schema.xml. This can
019     * happen if a table is removed from the schema.
020     * 
021     * It sets a project property called "impex.data.invalid". This property is a comma delimited list of filenames that
022     * have no match in the db schema.
023     * 
024     * @goal id-invalid-data-files
025     */
026    public class IdentifyInvalidDataFiles extends BaseMojo {
027            private static final String FS = System.getProperty("file.separator");
028    
029            /**
030             * @parameter expression="${extension}" default-value=".xml"
031             * @required
032             */
033            private String extension;
034    
035            /**
036             * @parameter expression="${dataDir}" default-value="${project.basedir}/src/main/impex"
037             * @required
038             */
039            private File dataDir;
040    
041            /**
042             * @parameter expression="${dataDirIncludes}" default-value="*.xml"
043             */
044            private String dataDirIncludes;
045    
046            /**
047             * @parameter expression="${dataDirExcludes}" default-value="schema.xml"
048             */
049            private String dataDirExcludes;
050    
051            /**
052             * @parameter expression="${schemaXMLFile}" default-value="src/main/impex/schema.xml"
053             */
054            private String schemaXMLFile;
055    
056            /**
057             * @parameter expression="${targetDatabase}" default-value="oracle"
058             */
059            private String targetDatabase;
060    
061            @Override
062            protected void executeMojo() throws MojoExecutionException, MojoFailureException {
063                    Utils utils = new Utils();
064                    try {
065                            getLog().info("Examining " + dataDir.getAbsolutePath());
066                            Database db = utils.getDatabase(schemaXMLFile, targetDatabase);
067                            DirectoryScanner ds = getDirectoryScanner();
068                            Set<File> existing = getExistingFiles(ds);
069                            Set<File> allowed = getDatabaseFiles(db);
070                            Set<File> invalid = SetUtils.difference(existing, allowed);
071                            getLog().info(existing.size() + " data files currently exist");
072                            getLog().info(invalid.size() + " of those are invalid");
073                            StringBuilder sb = new StringBuilder();
074                            int count = 0;
075                            for (File file : invalid) {
076                                    if (count != 0) {
077                                            sb.append(",");
078                                    }
079                                    sb.append("**/src/main/impex/" + file.getName());
080                                    getLog().info("Marked for removal: " + file.getName());
081                                    count++;
082                            }
083                            Properties properties = getProject().getProperties();
084                            properties.setProperty("impex.data.invalid", sb.toString());
085                    } catch (Exception e) {
086                            throw new MojoExecutionException("Error executing mojo", e);
087                    }
088            }
089    
090            protected Set<File> getDatabaseFiles(Database db) {
091                    List<?> tables = db.getTables();
092                    Set<File> files = new TreeSet<File>();
093                    for (Object object : tables) {
094                            Table table = (Table) object;
095                            String tableName = table.getName();
096                            String filename = dataDir.getAbsolutePath() + FS + tableName + extension;
097                            File file = new File(filename);
098                            files.add(file);
099                    }
100                    return files;
101            }
102    
103            protected Set<File> getExistingFiles(DirectoryScanner ds) {
104                    ds.scan();
105                    String[] relativeFilenames = ds.getIncludedFiles();
106                    Set<File> files = new TreeSet<File>();
107                    for (int i = 0; i < relativeFilenames.length; i++) {
108                            String filename = ds.getBasedir().getAbsolutePath() + FS + relativeFilenames[i];
109                            File file = new File(filename);
110                            files.add(file);
111                    }
112                    return files;
113            }
114    
115            protected DirectoryScanner getDirectoryScanner() {
116                    DirectoryScanner ds = new DirectoryScanner();
117                    ds.setBasedir(dataDir);
118                    ds.setIncludes(new String[] { dataDirIncludes });
119                    ds.setExcludes(new String[] { dataDirExcludes });
120                    return ds;
121            }
122    
123            protected File getFile(Table table) {
124                    String tableName = table.getName();
125                    String filename = dataDir.getAbsolutePath() + FS + tableName + extension;
126                    File file = new File(filename);
127                    return file;
128            }
129    
130            public File getDataDir() {
131                    return dataDir;
132            }
133    
134            public void setDataDir(File dataDir) {
135                    this.dataDir = dataDir;
136            }
137    
138            public String getDataDirIncludes() {
139                    return dataDirIncludes;
140            }
141    
142            public void setDataDirIncludes(String dataDirIncludes) {
143                    this.dataDirIncludes = dataDirIncludes;
144            }
145    
146            public String getDataDirExcludes() {
147                    return dataDirExcludes;
148            }
149    
150            public void setDataDirExcludes(String dataDirExcludes) {
151                    this.dataDirExcludes = dataDirExcludes;
152            }
153    
154            public String getSchemaXMLFile() {
155                    return schemaXMLFile;
156            }
157    
158            public void setSchemaXMLFile(String schemaXMLFile) {
159                    this.schemaXMLFile = schemaXMLFile;
160            }
161    
162            public String getExtension() {
163                    return extension;
164            }
165    
166            public void setExtension(String extension) {
167                    this.extension = extension;
168            }
169    
170            public String getTargetDatabase() {
171                    return targetDatabase;
172            }
173    
174            public void setTargetDatabase(String targetDatabase) {
175                    this.targetDatabase = targetDatabase;
176            }
177    
178    }