View Javadoc

1   /*
2    * Copyright 2006 Outsource Cafe, Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the 'License')
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *    http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an 'AS IS' BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.javagen.agile.db.visitor;
17  
18  import java.util.List;
19  import java.util.Set;
20  
21  import org.javagen.agile.core.model.Model;
22  import org.javagen.agile.db.model.Column;
23  import org.javagen.agile.db.model.ColumnReference;
24  import org.javagen.agile.db.model.Database;
25  import org.javagen.agile.db.model.FkConstraint;
26  import org.javagen.agile.db.model.PkColumn;
27  import org.javagen.agile.db.model.Table;
28  import org.javagen.agile.db.model.UniqueConstraint;
29  
30  /***
31   * Traversal part of visitor pattern as applied to database hierarchy.
32   * <p>
33   * CAUTION: For some applications it may be necessary to walks the tree twice to avoid null references.
34   * Once to visit tables and columns and a 
35   * second pass to visit the foreign keys and their references after all tables/columns have been processed. 
36   * <p> 
37   * In these situations implement the <code>Generator</code> interface like so:
38   * <pre>
39   * public void gen(Model database) {
40   *   DatabaseWalker.walk(database, visitor, DatabaseVisitor.NON_FK_MODEL_TYPES);
41   *   DatabaseWalker.walk(database, visitor, DatabaseVisitor.FK_ONLY_MODEL_TYPES);
42   *   return database;
43   * }
44   * </pre>
45   * 
46   * @author Richard Easterling
47   */
48  public class DatabaseWalker {
49  
50      /***
51       * Walk the database model tree using the visitor's itinerary.
52       * 
53       * @param database root node of the tree
54       * @param visitor implementation to apply to the tree
55       */
56      public static void walk(Database database, DatabaseVisitor visitor) {
57  		if (database==null)
58  			throw new NullPointerException("DatabaseWalker called with null dataase model instance");
59          walk(database, visitor, visitor.itinerary());
60  	}
61  	
62      public static void walk(Model model, DatabaseVisitor visitor, Set<String> itinerary) {
63          if (itinerary==null || itinerary.contains(model.getModelType())) {
64              if (model instanceof PkColumn) {
65                  visitor.visit( (PkColumn)model );
66              } else if (model instanceof Column) {
67                  visitor.visit( (Column)model );
68              } else if (model instanceof FkConstraint) {
69                  visitor.visit( (FkConstraint)model );
70              } else if (model instanceof ColumnReference) {
71                  visitor.visit( (ColumnReference)model );
72              } else if (model instanceof Table) {
73                  visitor.visit( (Table)model );
74              } else if (model instanceof Database) {
75                  visitor.visit( (Database)model );
76              } else if (model instanceof UniqueConstraint) {
77                  visitor.visit( (UniqueConstraint)model );
78              } else {
79                  visitor.visit( model );
80              }
81          }
82          List<Model> children = model.allOwnedModels();
83          if ( children!= null) {
84              for(Model child : children) {
85                  walk(child, visitor, itinerary);
86              }
87          }
88      }
89  
90  }