%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.torque.task.TorqueDataModelTask |
|
|
1 | package org.apache.torque.task; |
|
2 | ||
3 | /* |
|
4 | * Copyright 2001-2005 The Apache Software Foundation. |
|
5 | * |
|
6 | * Licensed under the Apache License, Version 2.0 (the "License") |
|
7 | * you may not use this file except in compliance with the License. |
|
8 | * You may obtain a copy of the License at |
|
9 | * |
|
10 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
11 | * |
|
12 | * Unless required by applicable law or agreed to in writing, software |
|
13 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
15 | * See the License for the specific language governing permissions and |
|
16 | * limitations under the License. |
|
17 | */ |
|
18 | ||
19 | import java.io.File; |
|
20 | ||
21 | import java.util.ArrayList; |
|
22 | import java.util.Hashtable; |
|
23 | import java.util.Iterator; |
|
24 | import java.util.List; |
|
25 | ||
26 | import org.apache.commons.lang.StringUtils; |
|
27 | ||
28 | import org.apache.tools.ant.BuildException; |
|
29 | import org.apache.tools.ant.DirectoryScanner; |
|
30 | import org.apache.tools.ant.types.FileSet; |
|
31 | ||
32 | import org.apache.torque.engine.EngineException; |
|
33 | import org.apache.torque.engine.database.model.Database; |
|
34 | import org.apache.torque.engine.database.transform.XmlToAppData; |
|
35 | ||
36 | import org.apache.velocity.VelocityContext; |
|
37 | import org.apache.velocity.context.Context; |
|
38 | import org.apache.velocity.texen.ant.TexenTask; |
|
39 | ||
40 | /** |
|
41 | * A base torque task that uses either a single XML schema |
|
42 | * representing a data model, or a <fileset> of XML schemas. |
|
43 | * We are making the assumption that an XML schema representing |
|
44 | * a data model contains tables for a <strong>single</strong> |
|
45 | * database. |
|
46 | * |
|
47 | * @author <a href="mailto:jvanzyl@zenplex.com">Jason van Zyl</a> |
|
48 | * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a> |
|
49 | */ |
|
50 | 0 | public class TorqueDataModelTask extends TexenTask |
51 | { |
|
52 | /** |
|
53 | * XML that describes the database model, this is transformed |
|
54 | * into the application model object. |
|
55 | */ |
|
56 | protected String xmlFile; |
|
57 | ||
58 | /** Fileset of XML schemas which represent our data models. */ |
|
59 | 0 | protected List filesets = new ArrayList(); |
60 | ||
61 | /** Data models that we collect. One from each XML schema file. */ |
|
62 | 0 | protected List dataModels = new ArrayList(); |
63 | ||
64 | /** Velocity context which exposes our objects in the templates. */ |
|
65 | protected Context context; |
|
66 | ||
67 | /** |
|
68 | * Map of data model name to database name. |
|
69 | * Should probably stick to the convention of them being the same but |
|
70 | * I know right now in a lot of cases they won't be. |
|
71 | */ |
|
72 | protected Hashtable dataModelDbMap; |
|
73 | ||
74 | /** |
|
75 | * Hashtable containing the names of all the databases |
|
76 | * in our collection of schemas. |
|
77 | */ |
|
78 | protected Hashtable databaseNames; |
|
79 | ||
80 | //!! This is probably a crappy idea having the sql file -> db map |
|
81 | // here. I can't remember why I put it here at the moment ... |
|
82 | // maybe I was going to map something else. It can probably |
|
83 | // move into the SQL task. |
|
84 | ||
85 | /** |
|
86 | * Name of the properties file that maps an SQL file |
|
87 | * to a particular database. |
|
88 | */ |
|
89 | protected String sqldbmap; |
|
90 | ||
91 | /** The target database(s) we are generating SQL for. */ |
|
92 | private String targetDatabase; |
|
93 | ||
94 | /** Target Java package to place the generated files in. */ |
|
95 | private String targetPackage; |
|
96 | ||
97 | ||
98 | /** |
|
99 | * Set the sqldbmap. |
|
100 | * |
|
101 | * @param sqldbmap th db map |
|
102 | */ |
|
103 | public void setSqlDbMap(String sqldbmap) |
|
104 | { |
|
105 | //!! Make all these references files not strings. |
|
106 | 0 | this.sqldbmap = project.resolveFile(sqldbmap).toString(); |
107 | 0 | } |
108 | ||
109 | /** |
|
110 | * Get the sqldbmap. |
|
111 | * |
|
112 | * @return String sqldbmap. |
|
113 | */ |
|
114 | public String getSqlDbMap() |
|
115 | { |
|
116 | 0 | return sqldbmap; |
117 | } |
|
118 | ||
119 | /** |
|
120 | * Return the data models that have been processed. |
|
121 | * |
|
122 | * @return List data models |
|
123 | */ |
|
124 | public List getDataModels() |
|
125 | { |
|
126 | 0 | return dataModels; |
127 | } |
|
128 | ||
129 | /** |
|
130 | * Return the data model to database name map. |
|
131 | * |
|
132 | * @return Hashtable data model name to database name map. |
|
133 | */ |
|
134 | public Hashtable getDataModelDbMap() |
|
135 | { |
|
136 | 0 | return dataModelDbMap; |
137 | } |
|
138 | ||
139 | /** |
|
140 | * Get the xml schema describing the application model. |
|
141 | * |
|
142 | * @return String xml schema file. |
|
143 | */ |
|
144 | public String getXmlFile() |
|
145 | { |
|
146 | 0 | return xmlFile; |
147 | } |
|
148 | ||
149 | /** |
|
150 | * Set the xml schema describing the application model. |
|
151 | * |
|
152 | * @param xmlFile The new XmlFile value |
|
153 | */ |
|
154 | public void setXmlFile(String xmlFile) |
|
155 | { |
|
156 | 0 | this.xmlFile = project.resolveFile(xmlFile).toString(); |
157 | 0 | } |
158 | ||
159 | /** |
|
160 | * Adds a set of xml schema files (nested fileset attribute). |
|
161 | * |
|
162 | * @param set a Set of xml schema files |
|
163 | */ |
|
164 | public void addFileset(FileSet set) |
|
165 | { |
|
166 | 0 | filesets.add(set); |
167 | 0 | } |
168 | ||
169 | /** |
|
170 | * Get the current target database. |
|
171 | * |
|
172 | * @return String target database(s) |
|
173 | */ |
|
174 | public String getTargetDatabase() |
|
175 | { |
|
176 | 0 | return targetDatabase; |
177 | } |
|
178 | ||
179 | /** |
|
180 | * Set the current target database. (e.g. mysql, oracle, ..) |
|
181 | * |
|
182 | * @param v target database(s) |
|
183 | */ |
|
184 | public void setTargetDatabase(String v) |
|
185 | { |
|
186 | 0 | targetDatabase = v; |
187 | 0 | } |
188 | ||
189 | /** |
|
190 | * Get the current target package. |
|
191 | * |
|
192 | * @return return target java package. |
|
193 | */ |
|
194 | public String getTargetPackage() |
|
195 | { |
|
196 | 0 | return targetPackage; |
197 | } |
|
198 | ||
199 | /** |
|
200 | * Set the current target package. This is where generated java classes will |
|
201 | * live. |
|
202 | * |
|
203 | * @param v target java package. |
|
204 | */ |
|
205 | public void setTargetPackage(String v) |
|
206 | { |
|
207 | 0 | targetPackage = v; |
208 | 0 | } |
209 | ||
210 | /** |
|
211 | * Set up the initial context for generating the SQL from the XML schema. |
|
212 | * |
|
213 | * @return the context |
|
214 | * @throws Exception |
|
215 | */ |
|
216 | public Context initControlContext() throws Exception |
|
217 | { |
|
218 | XmlToAppData xmlParser; |
|
219 | ||
220 | 0 | if (xmlFile == null && filesets.isEmpty()) |
221 | { |
|
222 | 0 | throw new BuildException("You must specify an XML schema or " |
223 | + "fileset of XML schemas!"); |
|
224 | } |
|
225 | ||
226 | try |
|
227 | { |
|
228 | 0 | if (xmlFile != null) |
229 | { |
|
230 | // Transform the XML database schema into |
|
231 | // data model object. |
|
232 | 0 | xmlParser = new XmlToAppData(getTargetDatabase(), |
233 | getTargetPackage()); |
|
234 | 0 | Database ad = xmlParser.parseFile(xmlFile); |
235 | 0 | ad.setFileName(grokName(xmlFile)); |
236 | 0 | dataModels.add(ad); |
237 | } |
|
238 | else |
|
239 | { |
|
240 | // Deal with the filesets. |
|
241 | 0 | for (int i = 0; i < filesets.size(); i++) |
242 | { |
|
243 | 0 | FileSet fs = (FileSet) filesets.get(i); |
244 | 0 | DirectoryScanner ds = fs.getDirectoryScanner(project); |
245 | 0 | File srcDir = fs.getDir(project); |
246 | ||
247 | 0 | String[] dataModelFiles = ds.getIncludedFiles(); |
248 | ||
249 | // Make a transaction for each file |
|
250 | 0 | for (int j = 0; j < dataModelFiles.length; j++) |
251 | { |
|
252 | 0 | File f = new File(srcDir, dataModelFiles[j]); |
253 | 0 | xmlParser = new XmlToAppData(getTargetDatabase(), |
254 | getTargetPackage()); |
|
255 | 0 | Database ad = xmlParser.parseFile(f.toString()); |
256 | 0 | ad.setFileName(grokName(f.toString())); |
257 | 0 | dataModels.add(ad); |
258 | } |
|
259 | } |
|
260 | } |
|
261 | ||
262 | 0 | Iterator i = dataModels.iterator(); |
263 | 0 | databaseNames = new Hashtable(); |
264 | 0 | dataModelDbMap = new Hashtable(); |
265 | ||
266 | // Different datamodels may state the same database |
|
267 | // names, we just want the unique names of databases. |
|
268 | 0 | while (i.hasNext()) |
269 | { |
|
270 | 0 | Database database = (Database) i.next(); |
271 | 0 | databaseNames.put(database.getName(), database.getName()); |
272 | 0 | dataModelDbMap.put(database.getFileName(), database.getName()); |
273 | } |
|
274 | } |
|
275 | 0 | catch (EngineException ee) |
276 | { |
|
277 | 0 | throw new BuildException(ee); |
278 | 0 | } |
279 | ||
280 | 0 | context = new VelocityContext(); |
281 | ||
282 | // Place our set of data models into the context along |
|
283 | // with the names of the databases as a convenience for now. |
|
284 | 0 | context.put("dataModels", dataModels); |
285 | 0 | context.put("databaseNames", databaseNames); |
286 | 0 | context.put("targetDatabase", targetDatabase); |
287 | 0 | context.put("targetPackage", targetPackage); |
288 | ||
289 | 0 | return context; |
290 | } |
|
291 | ||
292 | /** |
|
293 | * Gets a name to use for the application's data model. |
|
294 | * |
|
295 | * @param xmlFile The path to the XML file housing the data model. |
|
296 | * @return The name to use for the <code>AppData</code>. |
|
297 | */ |
|
298 | private String grokName(String xmlFile) |
|
299 | { |
|
300 | // This can't be set from the file name as it is an unreliable |
|
301 | // method of naming the descriptor. Not everyone uses the same |
|
302 | // method as I do in the TDK. jvz. |
|
303 | ||
304 | 0 | String name = "data-model"; |
305 | 0 | int i = xmlFile.lastIndexOf(System.getProperty("file.separator")); |
306 | 0 | if (i != -1) |
307 | { |
|
308 | // Creep forward to the start of the file name. |
|
309 | 0 | i++; |
310 | ||
311 | 0 | int j = xmlFile.lastIndexOf('.'); |
312 | 0 | if (i < j) |
313 | { |
|
314 | 0 | name = xmlFile.substring(i, j); |
315 | } |
|
316 | else |
|
317 | { |
|
318 | // Weirdo |
|
319 | 0 | name = xmlFile.substring(i); |
320 | } |
|
321 | } |
|
322 | 0 | return name; |
323 | } |
|
324 | ||
325 | /** |
|
326 | * Override Texen's context properties to map the |
|
327 | * torque.xxx properties (including defaults set by the |
|
328 | * org/apache/torque/defaults.properties) to just xxx. |
|
329 | * |
|
330 | * <p> |
|
331 | * Also, move xxx.yyy properties to xxxYyy as Velocity |
|
332 | * doesn't like the xxx.yyy syntax. |
|
333 | * </p> |
|
334 | * |
|
335 | * @param file the file to read the properties from |
|
336 | */ |
|
337 | public void setContextProperties(String file) |
|
338 | { |
|
339 | 0 | super.setContextProperties(file); |
340 | ||
341 | // Map the torque.xxx elements from the env to the contextProperties |
|
342 | 0 | Hashtable env = super.getProject().getProperties(); |
343 | 0 | for (Iterator i = env.keySet().iterator(); i.hasNext();) |
344 | { |
|
345 | 0 | String key = (String) i.next(); |
346 | 0 | if (key.startsWith("torque.")) |
347 | { |
|
348 | 0 | String newKey = key.substring("torque.".length()); |
349 | 0 | int j = newKey.indexOf("."); |
350 | 0 | while (j != -1) |
351 | { |
|
352 | 0 | newKey = |
353 | newKey.substring(0, j) |
|
354 | + StringUtils.capitalize(newKey.substring(j + 1)); |
|
355 | 0 | j = newKey.indexOf("."); |
356 | } |
|
357 | ||
358 | 0 | contextProperties.setProperty(newKey, env.get(key)); |
359 | } |
|
360 | } |
|
361 | 0 | } |
362 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |