View Javadoc

1   package org.apache.torque.mojo;
2   
3   import java.io.File;
4   import java.io.FileInputStream;
5   import java.io.IOException;
6   import java.io.InputStream;
7   import java.io.OutputStream;
8   import java.util.HashSet;
9   import java.util.List;
10  import java.util.Properties;
11  import java.util.Set;
12  import java.util.TreeSet;
13  
14  import org.apache.commons.io.FileUtils;
15  import org.apache.commons.io.IOUtils;
16  import org.apache.maven.plugin.MojoExecutionException;
17  import org.apache.maven.plugin.MojoFailureException;
18  import org.apache.tools.ant.DirectoryScanner;
19  import org.apache.torque.engine.database.model.Database;
20  import org.apache.torque.engine.database.model.Table;
21  import org.kuali.core.db.torque.SetUtils;
22  import org.kuali.core.db.torque.Utils;
23  
24  /**
25   * This mojo identifies data files that are present on the file system but are not present in schema.xml. This can
26   * happen if a table is removed from the schema.
27   * 
28   * It sets a project property called "impex.data.invalid". This property is a comma delimited list of filenames that
29   * have no match in the db schema.
30   * 
31   * If it finds any invalid files it will also set the project property "impex.found.invalid=true"
32   * 
33   * @goal id-invalid-data-files
34   */
35  public class IdentifyInvalidDataFiles extends BaseMojo {
36      private static final String FS = System.getProperty("file.separator");
37  
38      /**
39       * @parameter expression="${extension}" default-value=".xml"
40       * @required
41       */
42      private String extension;
43  
44      /**
45       * @parameter expression="${dataDir}" default-value="${project.basedir}/src/main/impex"
46       * @required
47       */
48      private File dataDir;
49  
50      /**
51       * @parameter expression="${dataDirIncludes}" default-value="*.xml"
52       */
53      private String dataDirIncludes;
54  
55      /**
56       * @parameter expression="${dataDirExcludes}" default-value="schema.xml"
57       */
58      private String dataDirExcludes;
59  
60      /**
61       * @parameter expression="${schemaXMLFile}" default-value="src/main/impex/schema.xml"
62       */
63      private String schemaXMLFile;
64  
65      /**
66       * @parameter expression="${targetDatabase}" default-value="oracle"
67       */
68      private String targetDatabase;
69  
70      /**
71       * Any invalid files are listed in this file. One file per line
72       * 
73       * @parameter expression="${impex.markedForRemoval}" default-value="${project.build.directory}/impex/invalid.txt"
74       */
75      private File markedForRemoval;
76  
77      protected Set<File> getExportedFiles() throws MojoExecutionException {
78          String filename = getProject().getBuild().getDirectory() + "/impex/exported-tables.txt";
79          File file = new File(filename);
80          if (!file.exists()) {
81              getLog().warn("Could not locate " + file.getAbsolutePath());
82              return new HashSet<File>();
83          }
84          List<String> tablenames = getContents(file);
85          return getExportedFiles(tablenames);
86      }
87  
88      protected Set<File> getExportedFiles(List<String> tablenames) {
89          Set<File> files = new TreeSet<File>();
90          for (String tablename : tablenames) {
91              String filename = dataDir.getAbsolutePath() + FS + tablename + extension;
92              File file = new File(filename);
93              files.add(file);
94          }
95          return files;
96      }
97  
98      @SuppressWarnings("unchecked")
99      protected List<String> getContents(File file) throws MojoExecutionException {
100         InputStream in = null;
101         try {
102             in = new FileInputStream(file);
103             return IOUtils.readLines(in);
104         } catch (IOException e) {
105             throw new MojoExecutionException("Unexpected error", e);
106         } finally {
107             IOUtils.closeQuietly(in);
108         }
109     }
110 
111     @Override
112     protected void executeMojo() throws MojoExecutionException, MojoFailureException {
113         Utils utils = new Utils();
114         try {
115             getLog().info("Examining " + dataDir.getAbsolutePath());
116             Database db = utils.getDatabase(schemaXMLFile, targetDatabase);
117             DirectoryScanner ds = getDirectoryScanner();
118             Set<File> existing = getExistingFiles(ds);
119             Set<File> exported = getExportedFiles();
120             Set<File> allowed = getDatabaseFiles(db);
121             if (exported.size() > 0) {
122                 allowed = exported;
123             }
124             Set<File> invalid = SetUtils.difference(existing, allowed);
125             getLog().info(existing.size() + " data files currently exist");
126             getLog().info(invalid.size() + " of those are invalid");
127             StringBuilder sb = new StringBuilder();
128             int count = 0;
129             StringBuilder invalidFiles = new StringBuilder();
130             for (File file : invalid) {
131                 if (count != 0) {
132                     sb.append(",");
133                 }
134                 sb.append("**/src/main/impex/" + file.getName());
135                 invalidFiles.append(file.getCanonicalPath() + "\n");
136                 getLog().info("Marked for removal: " + file.getName());
137                 count++;
138             }
139             Properties properties = getProject().getProperties();
140             properties.setProperty("impex.data.invalid", sb.toString());
141             if (count > 0) {
142                 properties.setProperty("impex.found.invalid", Boolean.TRUE.toString());
143                 createFile(markedForRemoval, invalidFiles.toString());
144             }
145         } catch (Exception e) {
146             throw new MojoExecutionException("Error executing mojo", e);
147         }
148     }
149 
150     protected void createFile(File file, String contents) throws IOException {
151         OutputStream out = null;
152         try {
153             out = FileUtils.openOutputStream(file);
154             IOUtils.write(contents, out);
155         } finally {
156             IOUtils.closeQuietly(out);
157         }
158     }
159 
160     protected Set<File> getDatabaseFiles(Database db) {
161         List<?> tables = db.getTables();
162         Set<File> files = new TreeSet<File>();
163         for (Object object : tables) {
164             Table table = (Table) object;
165             String tableName = table.getName();
166             String filename = dataDir.getAbsolutePath() + FS + tableName + extension;
167             File file = new File(filename);
168             files.add(file);
169         }
170         return files;
171     }
172 
173     protected Set<File> getExistingFiles(DirectoryScanner ds) {
174         ds.scan();
175         String[] relativeFilenames = ds.getIncludedFiles();
176         Set<File> files = new TreeSet<File>();
177         for (int i = 0; i < relativeFilenames.length; i++) {
178             String filename = ds.getBasedir().getAbsolutePath() + FS + relativeFilenames[i];
179             File file = new File(filename);
180             files.add(file);
181         }
182         return files;
183     }
184 
185     protected DirectoryScanner getDirectoryScanner() {
186         DirectoryScanner ds = new DirectoryScanner();
187         ds.setBasedir(dataDir);
188         ds.setIncludes(new String[] { dataDirIncludes });
189         ds.setExcludes(new String[] { dataDirExcludes });
190         return ds;
191     }
192 
193     protected File getFile(Table table) {
194         String tableName = table.getName();
195         String filename = dataDir.getAbsolutePath() + FS + tableName + extension;
196         File file = new File(filename);
197         return file;
198     }
199 
200     public File getDataDir() {
201         return dataDir;
202     }
203 
204     public void setDataDir(File dataDir) {
205         this.dataDir = dataDir;
206     }
207 
208     public String getDataDirIncludes() {
209         return dataDirIncludes;
210     }
211 
212     public void setDataDirIncludes(String dataDirIncludes) {
213         this.dataDirIncludes = dataDirIncludes;
214     }
215 
216     public String getDataDirExcludes() {
217         return dataDirExcludes;
218     }
219 
220     public void setDataDirExcludes(String dataDirExcludes) {
221         this.dataDirExcludes = dataDirExcludes;
222     }
223 
224     public String getSchemaXMLFile() {
225         return schemaXMLFile;
226     }
227 
228     public void setSchemaXMLFile(String schemaXMLFile) {
229         this.schemaXMLFile = schemaXMLFile;
230     }
231 
232     public String getExtension() {
233         return extension;
234     }
235 
236     public void setExtension(String extension) {
237         this.extension = extension;
238     }
239 
240     public String getTargetDatabase() {
241         return targetDatabase;
242     }
243 
244     public void setTargetDatabase(String targetDatabase) {
245         this.targetDatabase = targetDatabase;
246     }
247 
248     public File getMarkedForRemoval() {
249         return markedForRemoval;
250     }
251 
252     public void setMarkedForRemoval(File markedForRemoval) {
253         this.markedForRemoval = markedForRemoval;
254     }
255 
256 }