View Javadoc

1   package org.andromda.core.dbmapping;
2   
3   import java.io.File;
4   import java.io.IOException;
5   import java.text.MessageFormat;
6   import java.util.ArrayList;
7   import java.util.Collections;
8   import java.util.Map;
9   import java.util.HashMap;
10  import java.util.HashSet;
11  import java.util.Iterator;
12  import java.util.List;
13  import java.util.Set;
14  
15  import org.andromda.core.common.DbMappingTable;
16  import org.andromda.core.common.RepositoryReadException;
17  
18  import org.apache.commons.digester.Digester;
19  
20  
21  /***
22   * <p>Implements DbMappingTable by using a Jakarta Commons Digester to
23   * read the <code>TypeMappings.xml</code> file.</p>
24   * 
25   * @author Stefan Kuehnel
26   * @author Matthias Bohlen
27   * @author <a href="http://www.amowers.com">Anthony Mowers</a>
28   *
29   * @see <a href="http://jakarta.apache.org/commons/digester/">Jakarta Commons Digester</a>
30   */
31  public class DigesterDbMappingTable
32      implements DbMappingTable 
33  {
34      private Map map = Collections.EMPTY_MAP;
35      private Digester digester = new Digester();
36  
37      public DigesterDbMappingTable()
38      {
39          digester.addObjectCreate("mappings", Mappings.class);
40          digester.addSetProperties("mappings", "database", "database");
41          digester.addObjectCreate("mappings/mapping", Mapping.class);
42          digester.addCallMethod("mappings/mapping/type", "addJavaType", 0);
43          digester.addObjectCreate("mappings/mapping/jdbc-type", JdbcType.class);
44          digester.addSetProperties("mappings/mapping/jdbc-type", "name", "name");
45          digester.addSetNext("mappings/mapping/jdbc-type", "setJdbcType");
46          digester.addObjectCreate("mappings/mapping/sql-type", SqlType.class);
47          digester.addSetProperties("mappings/mapping/sql-type",
48                                    new String[] { "pattern", "default-length" },
49                                    new String[] { "pattern", "defaultLength" });
50          digester.addSetNext("mappings/mapping/sql-type", "setSqlType");
51          digester.addSetNext("mappings/mapping", "addMapping");
52      }
53  
54      /***
55       * @see org.andromda.core.common.DbMappingTable#read(File)
56       */
57      public void read(File mappingsFile)
58          throws RepositoryReadException, IOException 
59      {
60  	try {
61              //ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
62              //ClassLoader classLoader = getClass().getClassLoader();
63              //digester.setClassLoader(classLoader);
64              Mappings mappings = (Mappings)digester.parse(mappingsFile);
65              initialize(mappings);
66  	} catch (Exception ex) {
67              throw new RepositoryReadException(
68                  "Error in TypeMappings file: " + mappingsFile, ex);
69  	}
70      }
71  
72      /***
73       * @see org.andromda.core.common.DbMappingTable#getJDBCType(String)
74       */
75      public String getJDBCType(String javaType)
76      {
77          Mapping m = (Mapping) map.get(javaType);
78          if (null == m)
79          {
80              return "** MISSING JDBC type mapping for " + javaType;
81          }
82  
83          return m.getJdbcType().getName();
84      }
85  
86      /***
87       * @see org.andromda.core.common.DbMappingTable#getSQLType(String, String)
88       */
89      public String getSQLType(String javaType, String desiredFieldLength) 
90      {
91          Mapping m = (Mapping) map.get(javaType);
92          if (null == m)
93          {
94              return "** MISSING SQL type mapping for " + javaType;
95          }
96          SqlType sqlType = m.getSqlType();
97  
98          String pattern = sqlType.getPattern();
99  
100         String fieldLength =
101             (null == desiredFieldLength)
102                 || ("".equals(desiredFieldLength))
103                     ? sqlType.getDefaultLength()
104                     : desiredFieldLength;
105         Object[] arguments = { fieldLength };
106 
107         return MessageFormat.format(pattern, arguments);
108     }
109 
110     private void initialize(Mappings mappings)
111     {
112         map = new HashMap();
113         
114         for (Iterator i = mappings.getMappings().iterator(); i.hasNext(); )
115         {
116             Mapping mapping = (Mapping)i.next();
117             for (Iterator j = mapping.getJavaTypes().iterator(); j.hasNext(); )
118             {
119                 String type = (String)j.next();
120                 if (map.containsKey(type)) {
121                     System.out.println("WARNING: Duplicate mappings for Java type '"+type+"'. Using new value.");
122                 }
123                 map.put(type, mapping);
124             }
125         }
126     }
127 
128     public static class Mappings {
129         private List mappings = new ArrayList();
130         private String database;
131 
132         /***
133          * Gets the list of mappings.
134          *
135          * @return a List with all mappings
136          */
137         public List getMappings() {
138             return mappings;
139         }
140 
141         /***
142          * Adds the given mapping to our list.
143          *
144          * @param m the new mapping to add
145          */
146         public void addMapping(Mapping m) {
147             mappings.add(m);
148         }
149 
150         /***
151          * Gets the name of the database this mappings are for.
152          *
153          * @return a String with the name of the database this mappings are for
154          */
155         public String getDatabase() {
156             return database;
157         }
158 
159         /***
160          * Sets the name of the database this mappings are for.
161          *
162          * @param database String with the name of the database this mappings are for
163          */
164         public void setDatabase(String database) {
165             this.database = database;
166         }
167     }
168 
169     public static class Mapping {
170         private Set javaTypes = new HashSet();
171         private JdbcType jdbcType;
172         private SqlType sqlType;
173 
174         /***
175          * Gets the Java types this mapping applies to.
176          *
177          * @return a Set with the Java types this mapping applies to
178          */
179         public Set getJavaTypes() {
180             return javaTypes;
181         }
182 
183         /***
184          * Adds a Java type this mapping applies to.
185          *
186          * @param javaType a String with a Java type this mapping applies to
187          */
188         public void addJavaType(String javaType) {
189             javaTypes.add(javaType);
190         }
191 
192         /***
193          * Gets the JDBC type the Java types map to.
194          * 
195          * @return the JdbcType the Java types map to
196          */
197         public JdbcType getJdbcType() {
198             return jdbcType;
199         }
200 
201         /***
202          * Sets the JDBC type the Java types map to.
203          * 
204          * @param jdbcType the JdbcType the Java types map to
205          */
206         public void setJdbcType(JdbcType jdbcType) {
207             this.jdbcType = jdbcType;
208         }
209 
210         /***
211          * Gets the SQL type the Java types map to.
212          * 
213          * @return the SqlType the Java types map to
214          */
215         public SqlType getSqlType() {
216             return sqlType;
217         }
218 
219         /***
220          * Sets the SQL type the Java types map to.
221          * 
222          * @param sqlType the SqlType the Java types map to
223          */
224         public void setSqlType(SqlType sqlType) {
225             this.sqlType = sqlType;
226         }
227 
228     }
229 
230     public static class JdbcType {
231         private String name;
232 
233         /***
234          * Gets the name of the JDBC type.
235          *
236          * @return a String with the name of the JDBC type
237          */
238         public String getName() {
239             return name;
240         }
241 
242         /***
243          * Sets the name of the JDBC type.
244          *
245          * @param name a String with the name of the JDBC type
246          */
247         public void setName(String name) {
248             this.name = name;
249         }
250     }
251 
252     public static class SqlType {
253         private String pattern;
254         private String defaultLength;
255 
256         /***
257          * Gets the pattern to build the SQL type.
258          *
259          * @return a String with the pattern to build the SQL type
260          */
261         public String getPattern() {
262             return pattern;
263         }
264 
265         /***
266          * Sets the pattern to build the SQL type.
267          *
268          * @param pattern a String with the pattern to build the SQL type
269          */
270         public void setPattern(String pattern) {
271             this.pattern = pattern;
272         }
273 
274         /***
275          * Gets the default length for the SQL type.
276          *
277          * @return a String with the default length for the SQL type
278          */
279         public String getDefaultLength() {
280             return defaultLength;
281         }
282 
283         /***
284          * Sets the default length for the SQL type.
285          *
286          * @param defaultLength a String with the default length for the SQL type
287          */
288         public void setDefaultLength(String defaultLength) {
289             this.defaultLength = defaultLength;
290         }
291     }
292 
293 }