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