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