1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.anttasks;
18
19 import java.io.File;
20 import java.io.FileOutputStream;
21 import java.io.IOException;
22 import java.io.OutputStreamWriter;
23 import java.io.PrintWriter;
24 import java.util.ArrayList;
25 import java.util.Iterator;
26 import java.util.List;
27
28 import org.apache.tools.ant.BuildException;
29 import org.apache.tools.ant.DirectoryScanner;
30 import org.apache.tools.ant.Task;
31 import org.apache.tools.ant.types.AbstractFileSet;
32 import org.apache.tools.ant.types.Reference;
33
34 /***
35 * ArchetypeDescriptor
36 *
37 * This Ant task is used to generate a Maven2 Archetype Descriptor file.
38 *
39 * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
40 * @version $Id: $
41 */
42 public class ArchetypeDescriptor extends Task
43 {
44 private String header;
45 private String artifactId;
46 private Boolean allowPartial = new Boolean(true);
47 private File baseDir;
48 private File destFile;
49 private Reference sourcesRefId;
50 private Reference resourcesRefId;
51 private Reference testSourcesRefId;
52 private Reference testResourcesRefId;
53 private Reference siteResourcesRefId;
54
55 /***
56 * Set archetype descriptor header text
57 *
58 * @param header archetype header text
59 */
60 public void addText(String header)
61 {
62 this.header = getProject().replaceProperties(header);
63 }
64
65 /***
66 * Set archetype artifact id.
67 *
68 * @param artifactId archetype artifact id
69 */
70 public void setArtifactid(String artifactId)
71 {
72 this.artifactId = artifactId;
73 }
74
75 /***
76 * Set archetype partial rules to support execution in existing projects.
77 *
78 * @param allowPartial archetype allow partial setting
79 */
80 public void setAllowpartial(Boolean allowPartial)
81 {
82 this.allowPartial = allowPartial;
83 }
84
85 /***
86 * Set archetype base directory for all sources/resources.
87 *
88 * @param baseDir archtype source/resource base directory
89 */
90 public void setBasedir(File baseDir)
91 {
92 this.baseDir = baseDir;
93 }
94
95 /***
96 * Set archetype descriptor destination file.
97 *
98 * @param destFile archetype descriptor file to generate
99 */
100 public void setDestfile(File destFile)
101 {
102 this.destFile = destFile;
103 }
104
105 /***
106 * Set archetype sources refid.
107 *
108 * @param sourcesRefId archetype sources
109 */
110 public void setSourcesrefid(Reference sourcesRefId)
111 {
112 this.sourcesRefId = sourcesRefId;
113 }
114
115 /***
116 * Set archetype resources fileset refid.
117 *
118 * @param resourcesRefId archetype resources
119 */
120 public void setResourcesrefid(Reference resourcesRefId)
121 {
122 this.resourcesRefId = resourcesRefId;
123 }
124
125 /***
126 * Set archetype test sources fileset refid.
127 *
128 * @param testSourcesRefId archetype test sources
129 */
130 public void setTestsourcesrefid(Reference testSourcesRefId)
131 {
132 this.testSourcesRefId = testSourcesRefId;
133 }
134
135 /***
136 * Set archetype test resources fileset refid.
137 *
138 * @param testResourcesRefId archetype test resources
139 */
140 public void setTestresourcesrefid(Reference testResourcesRefId)
141 {
142 this.testResourcesRefId = testResourcesRefId;
143 }
144
145 /***
146 * Set archetype site resources fileset refid.
147 *
148 * @param siteResourcesRefId archetype site resources
149 */
150 public void setSiteresourcesrefid(Reference siteResourcesRefId)
151 {
152 this.siteResourcesRefId = siteResourcesRefId;
153 }
154
155 /***
156 * Executes task to generate desciptor file.
157 *
158 * @throws BuildException
159 */
160 public void execute() throws BuildException
161 {
162
163 if ((artifactId == null) || (baseDir == null) || (destFile == null))
164 {
165 throw new BuildException("required artifactid, basedir, or destfile attribute missing", getLocation());
166 }
167
168
169 List sources = archetypeFiles(sourcesRefId, "sourcesrefid");
170 List resources = archetypeFiles(resourcesRefId, "resourcesrefid");
171 List testSources = archetypeFiles(testSourcesRefId, "testsourcesrefid");
172 List testResources = archetypeFiles(testResourcesRefId, "testresourcesrefid");
173 List siteResources = archetypeFiles(siteResourcesRefId, "siteresourcesrefid");
174
175
176 PrintWriter writer = null;
177 try
178 {
179
180 File destDir = destFile.getParentFile();
181 if (!destDir.exists())
182 {
183 destDir.mkdirs();
184 }
185
186
187 writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(destFile), "UTF-8"));
188 writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
189 if (header != null)
190 {
191 writer.println(header);
192 }
193 writer.println("<archetype>");
194 writer.println(" <id>" + artifactId + "</id>");
195 writer.println(" <allowPartial>" + allowPartial + "</allowPartial>");
196 writeFiles(writer, "sources", "source", sources);
197 writeFiles(writer, "resources", "resource", resources);
198 writeFiles(writer, "testSources", "source", testSources);
199 writeFiles(writer, "testResources", "resource", testResources);
200 writeFiles(writer, "siteResources", "resource", siteResources);
201 writer.println("</archetype>");
202 }
203 catch (IOException ioe)
204 {
205 throw new BuildException("unable to write decriptor", ioe, getLocation());
206 }
207 finally
208 {
209 if (writer != null)
210 {
211 writer.close();
212 }
213 }
214
215
216 int archetypeSourcesCount = sources.size() + resources.size() + testSources.size() + testResources.size() + siteResources.size();
217 log("generated " + destFile + " including " + archetypeSourcesCount + " source/resource files");
218 }
219
220 /***
221 * Utility to read fileset refid attributes.
222 *
223 * @param refId attribute refid
224 * @param name attribute name
225 * @return list of String file paths
226 * @throws BuildException
227 */
228 private List archetypeFiles(Reference refId, String name) throws BuildException
229 {
230 List archetypeFiles = new ArrayList();
231 if (refId != null)
232 {
233
234 if (!(refId.getReferencedObject(getProject()) instanceof AbstractFileSet))
235 {
236 throw new BuildException(name + " attribute must reference a fileset", getLocation());
237 }
238 AbstractFileSet fileSet = (AbstractFileSet)refId.getReferencedObject(getProject());
239 DirectoryScanner directoryScanner = fileSet.getDirectoryScanner(getProject());
240 String [] files = directoryScanner.getIncludedFiles();
241 if ((files != null) && (files.length > 0))
242 {
243 String basePath = canonicalPath(baseDir);
244 for (int i = 0; (i < files.length); i++)
245 {
246
247
248 String archetypePath = files[i];
249 if (basePath != null)
250 {
251 File file = new File(fileSet.getDir(getProject()), files[i]);
252 String filePath = canonicalPath(file);
253 if ((filePath != null) && filePath.startsWith(basePath))
254 {
255
256 archetypePath = filePath.substring(basePath.length());
257 if (archetypePath.startsWith("/"))
258 {
259 archetypePath = archetypePath.substring(1);
260 }
261 }
262 }
263
264 archetypeFiles.add(archetypePath);
265 }
266 }
267 }
268 return archetypeFiles;
269 }
270
271 /***
272 * Utility to get canonical file path
273 *
274 * @param file file to convert to canonical path
275 * @return canonical path
276 */
277 private String canonicalPath(File file)
278 {
279 try
280 {
281 String path = file.getCanonicalPath();
282 return path.replace('//', '/');
283 }
284 catch (IOException ioe)
285 {
286 return null;
287 }
288 }
289
290 /***
291 * Utility to write archetype descriptor file lists.
292 *
293 * @param writer descriptor writer
294 * @param collectionElementName collection element name
295 * @param elementName file element name
296 * @param files list of String file paths
297 * @throws IOException
298 */
299 private void writeFiles(PrintWriter writer, String collectionElementName, String elementName, List files) throws IOException
300 {
301
302 if (!files.isEmpty())
303 {
304 writer.println(" <" + collectionElementName + ">");
305 Iterator fileIter = files.iterator();
306 while (fileIter.hasNext())
307 {
308 writer.println(" <" + elementName + ">" + (String)fileIter.next() + "</" + elementName + ">");
309 }
310 writer.println(" </" + collectionElementName + ">");
311 }
312 }
313 }