View Javadoc

1   /*
2    * joey-gen and its relative products are published under the terms
3    * of the Apache Software License.
4    * 
5    * Created on 2005/01/12 15:19:46
6    */
7   package org.asyrinx.joey.gen.task;
8   
9   import java.io.File;
10  import java.io.OutputStream;
11  import java.io.PrintWriter;
12  import java.util.ArrayList;
13  import java.util.Iterator;
14  import java.util.List;
15  import java.util.Map;
16  
17  import org.apache.commons.logging.Log;
18  import org.apache.commons.logging.LogFactory;
19  import org.apache.tools.ant.BuildException;
20  import org.apache.tools.ant.Task;
21  import org.apache.tools.ant.types.FileSet;
22  import org.asyrinx.brownie.core.lang.ObjectUtils;
23  import org.asyrinx.brownie.core.lang.StringUtils;
24  import org.asyrinx.joey.gen.command.rdb.StandardCommands;
25  import org.asyrinx.joey.gen.model.Element;
26  import org.asyrinx.joey.gen.model.ElementSet;
27  import org.asyrinx.joey.gen.model.EnumerationEntry;
28  import org.asyrinx.joey.gen.model.command.Command;
29  import org.asyrinx.joey.gen.model.rdb.Column;
30  import org.asyrinx.joey.gen.model.rdb.Database;
31  import org.asyrinx.joey.gen.model.rdb.Databases;
32  import org.asyrinx.joey.gen.model.rdb.ForeignKey;
33  import org.asyrinx.joey.gen.model.rdb.ForeignKeyEntry;
34  import org.asyrinx.joey.gen.model.rdb.Index;
35  import org.asyrinx.joey.gen.model.rdb.IndexEntry;
36  import org.asyrinx.joey.gen.model.rdb.RdbEnumeration;
37  import org.asyrinx.joey.gen.model.rdb.Table;
38  import org.asyrinx.joey.gen.model.rdb.TablePattern;
39  import org.asyrinx.joey.gen.model.rdb.TablePatternParam;
40  import org.asyrinx.joey.gen.task.impl.S2ContainerLoader;
41  import org.seasar.framework.container.S2Container;
42  
43  /***
44   * @author takeshi
45   */
46  public class JoeyModificationTask extends Task {
47  
48      protected final Log log = LogFactory.getLog(this.getClass());
49  
50      protected List filesets = new ArrayList();
51  
52      public void addFileset(FileSet set) {
53          filesets.add(set);
54      }
55  
56      private S2Container container = S2ContainerLoader.getContainer();
57  
58      public void execute() throws BuildException {
59          final ModelLoader modelLoader = (ModelLoader) container.getComponent(ModelLoader.class);
60          try {
61              final Databases currentModel = modelLoader.loadDatabaseModels(filesets, this.project);
62              final Databases lastModel = modelLoader.loadDatabaseModels(getLastSchemaFileSets(), this.project);
63              //チェック
64              final Command dbCommand = new StandardCommands();
65              dbCommand.execute(currentModel);
66              dbCommand.execute(lastModel);
67              //表示
68              final ShowModification showModification = new ShowModification(this.isShowNoChange(), this.isShowDeleted(),
69                      this.isShowAppended());
70              showModification.execute(currentModel, lastModel);
71          } catch (Exception e) {
72              throw new BuildException(e);
73          }
74      }
75  
76      private List getLastSchemaFileSets() {
77          final List result = new ArrayList();
78          final FileSet fs = new FileSet();
79          fs.setDir(this.getLastSchemaDir());
80          fs.setIncludes("*");
81          result.add(fs);
82          return result;
83      }
84  
85      private File lastSchemaDir = null;
86  
87      public File getLastSchemaDir() {
88          return lastSchemaDir;
89      }
90  
91      public void setLastSchemaDir(File lastSchemaDir) {
92          this.lastSchemaDir = lastSchemaDir;
93      }
94  
95      private boolean showNoChange = true;
96  
97      private boolean showDeleted = true;
98  
99      private boolean showAppended = true;
100 
101     public boolean isShowAppended() {
102         return showAppended;
103     }
104 
105     public void setShowAppended(boolean showAppended) {
106         this.showAppended = showAppended;
107     }
108 
109     public boolean isShowDeleted() {
110         return showDeleted;
111     }
112 
113     public void setShowDeleted(boolean showDeleted) {
114         this.showDeleted = showDeleted;
115     }
116 
117     public boolean isShowNoChange() {
118         return showNoChange;
119     }
120 
121     public void setShowNoChange(boolean showNoChange) {
122         this.showNoChange = showNoChange;
123     }
124 }
125 
126 interface ModificationView {
127     void show(Element current, Element last);
128 }
129 
130 class ShowModification {
131 
132     public ShowModification(boolean showNoChange, boolean showDeleted, boolean showAppended) {
133         super();
134         this.showNoChange = showNoChange;
135         this.showDeleted = showDeleted;
136         this.showAppended = showAppended;
137     }
138 
139     private final boolean showNoChange;
140 
141     private final boolean showDeleted;
142 
143     private final boolean showAppended;
144 
145     //protected final Log log = LogFactory.getLog(this.getClass());
146 
147     private PrintWriter writer = getWriter(getOutputStream());
148 
149     /***
150      * @param currentModel
151      * @param lastModel
152      */
153     public void execute(Databases currentModel, Databases lastModel) {
154         databasesView.show(currentModel, lastModel);
155     }
156 
157     interface ShowClosure {
158         void invoke(ModificationView view, String header, final Element lastElement, final Element currElement);
159     }
160 
161     final ShowClosure lastBaseClosure = new ShowClosure() {
162         public void invoke(ModificationView view, String header, final Element lastElement, final Element currElement) {
163             if (currElement == null) {
164                 if (isShowDeleted())
165                     printElementName("-", header, lastElement);
166             } else if (currElement.equals(lastElement)) {
167                 if (isShowNoChange())
168                     printElementName(" ", header, lastElement);
169                 if (view != null)
170                     view.show(currElement, lastElement);
171             } else {
172                 printElementName("!", header, lastElement);
173                 if (view != null)
174                     view.show(currElement, lastElement);
175             }
176         }
177     };
178 
179     final ShowClosure currentBaseClosure = new ShowClosure() {
180         public void invoke(ModificationView view, String header, final Element lastElement, final Element currElement) {
181             if (lastElement == null) {
182                 if (isShowAppended())
183                     printElementName("+", header, currElement);
184             }
185         }
186     };
187 
188     protected void showModification(ModificationView view, String header, ElementSet current, ElementSet last) {
189         if (ObjectUtils.equals(current, last)) {
190             if (!isShowNoChange())
191                 return;
192         }
193         if (current.careChildOrder())
194             showModificationByOrder(view, header, current, last);
195         else
196             showModificationByName(view, header, current, last);
197     }
198 
199     protected void showModificationByOrder(ModificationView view, String header, ElementSet current, ElementSet last) {
200         for (int i = 0; i < last.size(); i++) {
201             final Element lastElement = last.getElement(i);
202             final Element currElement = current.getElement(i);
203             lastBaseClosure.invoke(view, header, lastElement, currElement);
204         }
205         if (last.size() >= current.size())
206             return;
207         for (int i = last.size(); i < current.size(); i++) {
208             final Element lastElement = null;
209             final Element currElement = current.getElement(i);
210             currentBaseClosure.invoke(view, header, lastElement, currElement);
211         }
212     }
213 
214     protected void showModificationByName(ModificationView view, String header, ElementSet current, ElementSet last) {
215         for (Iterator i = last.iterator(); i.hasNext();) {
216             final Element lastElement = (Element) i.next();
217             final Element currElement = current.getElement(lastElement.getName());
218             lastBaseClosure.invoke(view, header, lastElement, currElement);
219         }
220         for (Iterator i = current.iterator(); i.hasNext();) {
221             final Element currElement = (Element) i.next();
222             final Element lastElement = last.getElement(currElement.getName());
223             currentBaseClosure.invoke(view, header, lastElement, currElement);
224         }
225     }
226 
227     void printElementName(String mark, String header, Element element) {
228         if (element != null) {
229             writer.println(mark + " " //
230                     + StringUtils.repeat(" ", (element.getAncestorDepth() - 1) * 4) //
231                     + StringUtils.padTail(header, " ", 12) // 
232                     + " : " + element.getName());
233         } else {
234             writer.println(mark + " " //
235                     + StringUtils.repeat(" ", 12) //
236                     + StringUtils.padTail(header, " ", 12) // 
237                     + " : " + "null");
238         }
239     }
240 
241     void printPropLine(Element element, String name, boolean last, boolean current) {
242         printPropLine(element, name, new Boolean(last), new Boolean(current));
243     }
244 
245     void printPropLine(Element element, String name, Object last, Object current) {
246         final int indent = element.getAncestorDepth() * 4;
247         if ((last instanceof Map) && (current instanceof Map)) {
248             printPropLineAsMap(indent + 4, name, (Map) last, (Map) current);
249         } else {
250             printPropLine(indent, name, last, current);
251         }
252     }
253 
254     void printPropLine(int indent, String name, Object last, Object current) {
255         if (ObjectUtils.equals(last, current)) {
256             if (!isShowNoChange())
257                 return;
258             writer.println(" " + " " // 
259                     + StringUtils.repeat(" ", indent) //
260                     + name + " : " + last);
261         } else {
262             writer.println("!" + " " // 
263                     + StringUtils.repeat(" ", indent) //
264                     + name + " : [" + last + "] -> [" + current + "]");
265         }
266     }
267 
268     void printPropLineAsMap(int indent, String name, Map last, Map current) {
269         if (ObjectUtils.equals(last, current)) {
270             if (!isShowNoChange())
271                 return;
272             writer.println(" " + " " // 
273                     + StringUtils.repeat(" ", indent) //
274                     + name + " : ");
275         } else {
276             writer.println("!" + " " // 
277                     + StringUtils.repeat(" ", indent) //
278                     + name + " : ");
279         }
280         for (Iterator i = last.keySet().iterator(); i.hasNext();) {
281             final Object key = i.next();
282             final Object lastValue = last.get(key);
283             final Object currValue = current.get(key);
284             printPropLine(indent + 4, key.toString(), lastValue, currValue);
285         }
286         for (Iterator i = current.keySet().iterator(); i.hasNext();) {
287             final Object key = i.next();
288             if (last.containsKey(key)) {
289                 //すでに出力しているキーは出力しない
290                 continue;
291             }
292             final Object lastValue = last.get(key);
293             final Object currValue = current.get(key);
294             printPropLine(indent + 4, key.toString(), lastValue, currValue);
295         }
296     }
297 
298     final ModificationView databasesView = new ModificationView() {
299         public void show(Element current, Element last) {
300             final Databases c = (Databases) current;
301             final Databases l = (Databases) last;
302             printPropLine(c, "options", l.getOptions(), c.getOptions());
303             showModification(databaseView, "database", c.getDatabases(), l.getDatabases());
304         }
305     };
306 
307     final ModificationView databaseView = new ModificationView() {
308         public void show(Element current, Element last) {
309             final Database c = (Database) current;
310             final Database l = (Database) last;
311             printPropLine(c, "options", l.getOptions(), c.getOptions());
312             showModification(enumView, "enum", c.getEnumerations(), l.getEnumerations());
313             showModification(tableView, "table", c.getTables(), l.getTables());
314         }
315     };
316 
317     final ModificationView enumView = new ModificationView() {
318         public void show(Element current, Element last) {
319             final RdbEnumeration c = (RdbEnumeration) current;
320             final RdbEnumeration l = (RdbEnumeration) last;
321             printPropLine(c, "options", l.getOptions(), c.getOptions());
322             showModification(enumEntryView, "enum-entry", c, l);
323         }
324     };
325 
326     final ModificationView enumEntryView = new ModificationView() {
327         public void show(Element current, Element last) {
328             final EnumerationEntry c = (EnumerationEntry) current;
329             final EnumerationEntry l = (EnumerationEntry) last;
330             printPropLine(c, "value", l.getValue(), c.getValue());
331             printPropLine(c, "options", l.getOptions(), c.getOptions());
332         }
333     };
334 
335     final ModificationView tableView = new ModificationView() {
336         public void show(Element current, Element last) {
337             final Table c = (Table) current;
338             final Table l = (Table) last;
339             printPropLine(c, "extends", l.getExtends(), c.getExtends());
340             printPropLine(c, "captionColumn", l.getCaptionColumn(), c.getCaptionColumn());
341             printPropLine(c, "options", l.getOptions(), c.getOptions());
342             showModification(columnView, "column", c.getColumns(), l.getColumns());
343             showModification(fkView, "foreignKey", c.getForeignKeys(), l.getForeignKeys());
344             showModification(indexView, "index", c.getIndexes(), l.getIndexes());
345             showModification(patternView, "pattern", c.getPatterns(), l.getPatterns());
346         }
347     };
348 
349     final ModificationView columnView = new ModificationView() {
350         public void show(Element current, Element last) {
351             final Column c = (Column) current;
352             final Column l = (Column) last;
353             printPropLine(c, "type", l.getType(), c.getType());
354             printPropLine(c, "size", l.getSize(), c.getSize());
355             printPropLine(c, "required", l.isRequired(), c.isRequired());
356             printPropLine(c, "primaryKey", l.isPrimaryKey(), c.isPrimaryKey());
357             printPropLine(c, "defaultValue", l.getDefaultValue(), c.getDefaultValue());
358             printPropLine(c, "enum", l.getEnum(), c.getEnum());
359             printPropLine(c, "options", l.getOptions(), c.getOptions());
360         }
361     };
362 
363     final ModificationView fkView = new ModificationView() {
364         public void show(Element current, Element last) {
365             final ForeignKey c = (ForeignKey) current;
366             final ForeignKey l = (ForeignKey) last;
367             printPropLine(c, "foreign", l.getForeign(), c.getForeign());
368             printPropLine(c, "type", l.getType(), c.getType());
369             printPropLine(c, "cascade", l.getCascade(), c.getCascade());
370             printPropLine(c, "options", l.getOptions(), c.getOptions());
371             showModification(fkEntryView, "reference", c, l);
372         }
373     };
374 
375     final ModificationView fkEntryView = new ModificationView() {
376         public void show(Element current, Element last) {
377             final ForeignKeyEntry c = (ForeignKeyEntry) current;
378             final ForeignKeyEntry l = (ForeignKeyEntry) last;
379             printPropLine(c, "local", l.getLocal(), c.getLocal());
380             printPropLine(c, "foreign", l.getForeign(), c.getForeign());
381             printPropLine(c, "options", l.getOptions(), c.getOptions());
382         }
383     };
384 
385     final ModificationView indexView = new ModificationView() {
386         public void show(Element current, Element last) {
387             final Index c = (Index) current;
388             final Index l = (Index) last;
389             printPropLine(c, "unique", l.isUnique(), c.isUnique());
390             printPropLine(c, "options", l.getOptions(), c.getOptions());
391             showModification(indexEntryView, "index-column", c, l);
392         }
393     };
394 
395     final ModificationView uniqueView = new ModificationView() {
396         public void show(Element current, Element last) {
397             final Index c = (Index) current;
398             final Index l = (Index) last;
399             printPropLine(c, "unique", l.isUnique(), c.isUnique());
400             printPropLine(c, "options", l.getOptions(), c.getOptions());
401             showModification(indexEntryView, "unique-column", c, l);
402         }
403     };
404 
405     final ModificationView indexEntryView = new ModificationView() {
406         public void show(Element current, Element last) {
407             final IndexEntry c = (IndexEntry) current;
408             final IndexEntry l = (IndexEntry) last;
409             printPropLine(c, "options", l.getOptions(), c.getOptions());
410         }
411     };
412 
413     final ModificationView patternView = new ModificationView() {
414         public void show(Element current, Element last) {
415             final TablePattern c = (TablePattern) current;
416             final TablePattern l = (TablePattern) last;
417             printPropLine(c, "options", l.getOptions(), c.getOptions());
418             showModification(patternParamView, "param", c, l);
419         }
420     };
421 
422     final ModificationView patternParamView = new ModificationView() {
423         public void show(Element current, Element last) {
424             final TablePatternParam c = (TablePatternParam) current;
425             final TablePatternParam l = (TablePatternParam) last;
426             printPropLine(c, "value", l.getValue(), c.getValue());
427             printPropLine(c, "options", l.getOptions(), c.getOptions());
428         }
429     };
430 
431     protected OutputStream getOutputStream() {
432         return System.out;
433     }
434 
435     protected PrintWriter getWriter(OutputStream stream) {
436         return new PrintWriter(stream) {
437             public void println(String x) {
438                 System.out.println(x);
439                 //super.println(x);
440             }
441         };
442     }
443 
444     public boolean isShowAppended() {
445         return showAppended;
446     }
447 
448     public boolean isShowDeleted() {
449         return showDeleted;
450     }
451 
452     public boolean isShowNoChange() {
453         return showNoChange;
454     }
455 }