1 package org.andromda.core.anttasks;
2
3 import java.io.File;
4 import java.text.MessageFormat;
5 import java.util.ArrayList;
6 import java.util.Collection;
7
8 import org.apache.tools.ant.BuildException;
9 import org.apache.tools.ant.DirectoryScanner;
10 import org.apache.tools.ant.Project;
11 import org.apache.tools.ant.types.FileSet;
12
13 /***
14 * This class implements the <code><template></code> tag
15 * which can used within the ant <code><andromda></code>
16 * tag to add additional code generation templates to androMDA.
17 *
18 * @author Matthias Bohlen
19 *
20 */
21 public class TemplateConfiguration
22 {
23
24 public TemplateConfiguration()
25 {
26 }
27
28 /***
29 * Constructor which is used to build default
30 * template configurations when initializing the AndroMDAGenTask.
31 *
32 * @param stereotype the name of the stereotype
33 * @param sheet name of the style sheet file
34 * @param outputPattern the pattern to build the output file name
35 * @param outputDir the output directory
36 * @param overwrite yes/no whether output file should be overwritten
37 */
38 public TemplateConfiguration(
39 String stereotype,
40 String sheet,
41 String outputPattern,
42 File outputDir,
43 boolean overwrite)
44 {
45 this.stereotype = stereotype;
46 this.sheet = sheet;
47 this.outputPattern = outputPattern;
48 this.outputDir = outputDir;
49 this.overwrite = overwrite;
50 this.transformClass = null;
51 }
52
53 /***
54 * Sets a reference to the ant project.
55 * Is used when the TemplateConfiguration object is added to the
56 * collection of templates in the AndroMDA ant task.
57 *
58 * @param p the project
59 */
60 void setProject(Project p)
61 {
62 this.project = p;
63 }
64
65 /***
66 * Sets the class name of object that the
67 * template code generation scripts will use
68 * to access the object model. The class must implement
69 * the ScriptHelper interface.
70 *
71 * <p> This is an optional parameter and if it is not set
72 * it defaults to the default transform class or the
73 * one which was configured using the
74 * <code><repository></code> tag. </p>
75 *
76 * <p> By writing ones own transformer class some of the
77 * more complicated code generation logic can be moved from
78 * the code generation script and into the transformer
79 * implementation. </p>
80 *
81 * @see org.andromda.core.common.ScriptHelper
82 *
83 * @param scriptHelperClassName
84 */
85 public void setTransformClassname(String scriptHelperClassName)
86 {
87 try {
88 transformClass = Class.forName(scriptHelperClassName);
89 }
90 catch (ClassNotFoundException cnfe)
91 {
92 new BuildException(cnfe);
93 }
94 }
95
96
97 /***
98 * Returns the class of the transform object
99 * that will be used to the code generation templates
100 * to access the object model.
101 *
102 * @return Class
103 */
104 public Class getTransformClass()
105 {
106 return transformClass;
107 }
108
109 /***
110 * Tells us the stereotype in the UML model that
111 * should drive code generation with this template.
112 * @param stereotype the name of the stereotype
113 */
114 public void setStereotype(String stereotype)
115 {
116 this.stereotype = stereotype;
117 }
118
119 /***
120 * Tells us the stereotype in the UML model that
121 * should drive code generation with this template.
122 * @return String the name of the stereotype
123 */
124 public String getStereotype()
125 {
126 return stereotype;
127 }
128
129 /***
130 * Tells us which Velocity stylesheet to use as a template.
131 * @param sheet points to the script
132 */
133 public void setSheet(String sheet)
134 {
135 this.sheet = sheet;
136 }
137
138 /***
139 * Tells us which Velocity stylesheet to use as a template.
140 * @return File points to the script
141 */
142 public String getSheet()
143 {
144 return sheet;
145 }
146
147 /***
148 * Sets the pattern that is used to build the
149 * name of the output file.
150 * @param outputPattern the pattern in java.text.MessageFormat syntax
151 */
152 public void setOutputPattern(String outputPattern)
153 {
154 this.outputPattern = outputPattern;
155 }
156
157 /***
158 * Gets the pattern that is used to build the
159 * name of the output file.
160 * @return String the pattern in java.text.MessageFormat syntax
161 */
162 public String getOutputPattern()
163 {
164 return outputPattern;
165 }
166
167 /***
168 * Sets the directory where the output file
169 * that is generated from this template should be placed,
170 * @param outputDir points to the output directory
171 */
172 public void setOutputDir(File outputDir)
173 {
174 this.outputDir = outputDir;
175 }
176
177 /***
178 * Sets the directory where the output file
179 * that is generated from this template should be placed,
180 * @return File points to the output directory
181 */
182 public File getOutputDir()
183 {
184 return outputDir;
185 }
186
187 /***
188 * Tells us whether output files generated by this
189 * template should be overwritten if they already exist.
190 * @param overwrite overwrite the file yes/no
191 */
192 public void setOverwrite(boolean overwrite)
193 {
194 this.overwrite = overwrite;
195 }
196
197 /***
198 * Tells us whether output files generated by this
199 * template should be overwritten if they already exist.
200 * @return boolean
201 */
202 public boolean isOverwrite()
203 {
204 return overwrite;
205 }
206
207 /***
208 * Creates a FileSet object when the <code><fileset></code> tag
209 * in the build.xml file is encountered.
210 * @return FileSet
211 */
212 public FileSet createFileset()
213 {
214 fileSet = new FileSet();
215 return fileSet;
216 }
217
218 public class TemplateSingleConfig
219 {
220 TemplateSingleConfig(String sheetName)
221 {
222 this.sheetName = sheetName;
223 }
224
225 /***
226 * Return the file name of the Velocity stylesheet.
227 * @return String the file name relative to the template path
228 */
229 public String getSheetName()
230 {
231 return sheetName;
232 }
233
234 /***
235 * Returns the fully qualified output file, that means:
236 * <ul>
237 * <li>the output pattern has been translated</li>
238 * <li>the output dir name has been prepended</li>
239 * </ul>
240 *
241 * @param inputClassName name of the class from the UML model
242 * @param inputPackageName name of the package from the UML model
243 * in which the class is contained
244 * @return File absolute file
245 */
246 public File getFullyQualifiedOutputFile(
247 String inputClassName,
248 String inputPackageName)
249 {
250 int dotIndex = sheetName.indexOf(".");
251 String sheetBaseName = sheetName.substring(0, dotIndex);
252
253 Object[] arguments =
254 {
255 inputPackageName.replace('.', '/'),
256 inputClassName,
257 sheetBaseName,
258 getStereotype()};
259
260 String outputFileName =
261 MessageFormat.format(outputPattern, arguments);
262
263 return new File(getOutputDir(), outputFileName);
264 }
265
266 private String sheetName;
267 }
268
269 /***
270 * Gets the template path of the configured templates.d
271 * If the "sheet" attribute was set, then return null,
272 * because the template will be searched relative to
273 * the "templatePath" attribute of the <code><uml2ejb></code> task.
274 * If the <code><fileset></code> element was given,
275 * then return the path of that fileset.
276 *
277 * @return String the template path or null
278 */
279 public String getTemplatePath()
280 {
281 if (sheet != null)
282 {
283 return null;
284 }
285
286 DirectoryScanner ds = fileSet.getDirectoryScanner(project);
287 return ds.getBasedir().getPath();
288 }
289
290 /***
291 * Gets a list of template files that were configured
292 * with the <code><fileset></code> tag.
293 * @return Collection a collection of templates, described by TemplateSingleConfig objects
294 * @see TemplateSingleConfig
295 */
296 public Collection getTemplateFiles()
297 {
298 ArrayList result = new ArrayList();
299 if (sheet != null)
300 {
301 result.add(new TemplateSingleConfig(sheet));
302 return result;
303 }
304
305 DirectoryScanner ds = fileSet.getDirectoryScanner(project);
306 String templateFiles[] = ds.getIncludedFiles();
307 for (int i = 0; i < templateFiles.length; i++)
308 {
309 result.add(new TemplateSingleConfig(templateFiles[i]));
310 }
311 return result;
312 }
313
314 /***
315 * Just for debugging.
316 * @see java.lang.Object#toString()
317 */
318 public String toString()
319 {
320 return "TemplateConfiguration: "
321 + stereotype
322 + " "
323 + sheet
324 + " "
325 + outputPattern
326 + " "
327 + outputDir
328 + " "
329 + overwrite
330 + " "
331 + fileSet;
332 }
333
334 private FileSet fileSet;
335 private String stereotype;
336 private String sheet;
337 private String outputPattern;
338 private File outputDir;
339 private boolean overwrite;
340 private Project project;
341 private Class transformClass;
342 }