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