1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.tools.ant.taskdefs.optional.sourceforge;
29
30 import java.io.File;
31
32 import java.util.Date;
33 import java.util.Enumeration;
34 import java.util.NoSuchElementException;
35 import java.util.Vector;
36
37 import org.apache.tools.ant.BuildException;
38 import org.apache.tools.ant.Task;
39
40 import sfutils.Administrator;
41 import sfutils.Project;
42
43 import sfutils.frs.FileRelease;
44 import sfutils.frs.FileSpecification;
45 import sfutils.frs.Package;
46
47 import sfutils.frs.web.HttpUnitPublisher;
48
49 /***
50 * An <a href="http://ant.apache.org/">Ant</a> {@link Task} that makes a file
51 * release available on <a href="http://sourceforge.net/">SourceForge</a>.
52 *
53 * @author <a href="mailto:ljnelson94@alumni.amherst.edu">Laird Nelson</a>
54 * @version $Revision: 1.10 $ $Date: 2003/07/12 16:13:24 $
55 * @since July 1, 2003
56 */
57 public class SourceForgePublish extends Task {
58
59 /***
60 * The {@link FileRelease} this {@link SourceForgePublish} {@link Task} will
61 * publish. This field will never be <code>null</code>.
62 */
63 private final FileRelease release;
64
65 /***
66 * The {@link FileSpec}s contained by this {@link SourceForgePublish} {@link
67 * Task}. This field will never be <code>null</code>.
68 */
69 private final Vector fileSpecs;
70
71 /***
72 * Creates a new {@link SourceForgePublish} {@link Task}.
73 */
74 public SourceForgePublish() {
75 super();
76 this.fileSpecs = new Vector();
77 this.release = createFileReleaseShell();
78 assertNotNull(this.release);
79 }
80
81 /***
82 * Creates a {@link FileRelease} with its associated {@link Package}, {@link
83 * Project} and {@link Administrator} set. The resulting {@link FileRelease}
84 * is in an illegal state until it is fully configured. This method never
85 * returns <code>null</code>.
86 *
87 * @return a {@link FileRelease} "shell"; never <code>null</code>
88 * @see FileRelease
89 */
90 private static final FileRelease createFileReleaseShell() {
91 final Package pkg = new Package();
92 final Project project = new Project();
93 final Administrator administrator = new Administrator();
94 final FileRelease fileRelease = new FileRelease();
95 project.setAdministrator(administrator);
96 pkg.setProject(project);
97 fileRelease.setPackage(pkg);
98 return fileRelease;
99 }
100
101 /***
102 * Called when the <code>releasename</code> XML attribute is encountered.
103 * Sets the {@link FileRelease}'s {@linkplain FileRelease#setName(String)
104 * name}.
105 *
106 * @param releaseName
107 * the name for the {@link FileRelease} that will be published;
108 * may be <code>null</code>
109 */
110 public void setReleaseName(final String releaseName) {
111 assertNotNull(this.release);
112 this.log("Setting releasename: " + releaseName);
113 this.release.setName(releaseName);
114 }
115
116 /***
117 * Called when the <code>hidden</code> XML attribute is encountered. Sets
118 * whether the {@link FileRelease} that will be published will be active or
119 * hidden.
120 *
121 * @param hidden
122 * if <code>true</code>, then the {@link FileRelease} that will
123 * be published will not be visible
124 */
125 public void setHidden(final boolean hidden) {
126 assertNotNull(this.release);
127 this.log("Setting hidden: " + hidden);
128 this.release.setHidden(hidden);
129 }
130
131 /***
132 * Called when the <code>packagename</code> XML attribute is encountered.
133 * Sets the {@linkplain Package#setName(String) <code>Package</code> name}.
134 *
135 * @param packageName
136 * the name for the {@link Package} to which the {@link
137 * FileRelease} that will be published belongs; may be
138 * <code>null</code>
139 */
140 public void setPackageName(final String packageName) {/package-summary.html">g> void setPackageName(final String packageName) {
141 assertNotNull(this.release);
142 final Package pkg = this.release.getPackage();
143 assertNotNull(pkg);
144 this.log("Setting packagename: " + packageName);
145 pkg.setName(packageName);
146 }
147
148 /***
149 * Called when the <code>packagehidden</code> XML attribute is encountered.
150 * Sets the {@linkplain Package#setHidden(boolean) visibility of the
151 * <code>Package</code>}.
152 *
153 * @param hidden
154 * if <code>true</code>, then the {@link Package} to which the
155 * {@link FileRelease} that will be published belongs will be
156 * marked as invisible
157 */
158 public void setPackageHidden(final boolean hidden) {
159 assertNotNull(this.release);
160 final Package pkg = this.release.getPackage();
161 assertNotNull(pkg);
162 this.log("Setting packagehidden: " + hidden);
163 pkg.setHidden(hidden);
164 }
165
166 /***
167 * Called when the <code>projectshortname</code> XML attribute is encountered.
168 * Sets the {@linkplain Project#setShortName(String) short name of the
169 * <code>Project</code>} to which the {@link FileRelease} that will be
170 * published belongs.
171 *
172 * @param shortName
173 * the short name of the {@link Project} to which the {@link
174 * FileRelease} that will be published belongs; may be
175 * <code>null</code>
176 */
177 public void setProjectShortName(final String shortName) {
178 assertNotNull(this.release);
179 final Package pkg = this.release.getPackage();
180 assertNotNull(pkg);
181 final Project project = pkg.getProject();
182 assertNotNull(project);
183 this.log("Setting projectshortname: " + shortName);
184 project.setShortName(shortName);
185 }
186
187 /***
188 * Called if a <code>projectlongname</code> XML attribute is encountered.
189 * Calls the {@link #setProjectName(String)} method.
190 *
191 * @param name
192 * the human-readable name for the {@link Project} to which the
193 * {@link FileRelease} that will be published belongs; may be
194 * <code>null</code>
195 */
196 public final void setProjectLongName(final String name) {
197 this.setProjectName(name);
198 }
199
200 /***
201 * Called when the <code>projectname</code> XML attribute is encountered.
202 * Sets the human-readable {@linkplain Project#setName(String) name of the
203 * <code>Project</code>} to which the {@link FileRelease} that will be
204 * published belongs.
205 *
206 * @param name
207 * the human-readable {@linkplain Project#setName(String) name
208 * of the <code>Project</code>} to which the {@link FileRelease}
209 * that will be published belongs; may be <code>null</code>
210 */
211 public void setProjectName(final String name) {
212 assertNotNull(this.release);
213 final Package pkg = this.release.getPackage();
214 assertNotNull(pkg);
215 final Project project = pkg.getProject();
216 assertNotNull(project);
217 this.log("Setting projectname: " + name);
218 project.setName(name);
219 }
220
221 /***
222 * Called when the <code>username</code> XML attribute is encountered. Sets
223 * the {@linkplain Administrator#setName(String) username of the
224 * <code>Administrator</code>} that governs the {@link Project} to which the
225 * {@link FileRelease} to be published belongs.
226 *
227 * @param userName
228 * the name for the associated {@link Administrator}; must not
229 * be <code>null</code>
230 * @exception BuildException
231 * if the supplied user name is <code>null</code>, equal to the
232 * empty {@link String}, or consists solely of whitespace
233 */
234 public void setUserName(final String userName)
235 throws BuildException {
236 assertNotNull(this.release);
237 final Package pkg = this.release.getPackage();
238 assertNotNull(pkg);
239 final Project project = pkg.getProject();
240 assertNotNull(project);
241 final Administrator admin = project.getAdministrator();
242 assertNotNull(admin);
243 this.log("Setting username: " + userName);
244 try {
245 admin.setName(userName);
246 } catch (final IllegalArgumentException kaboom) {
247 throw new BuildException(kaboom);
248 }
249 }
250
251 /***
252 * Called when the <code>password</code> XML attribute is encountered. Sets
253 * the {@linkplain Administrator#setPassword(String) password of the
254 * <code>Administrator</code>} that governs the {@link Project} to which the
255 * {@link FileRelease} to be published belongs.
256 *
257 * @param password
258 * the name for the associated {@link Administrator}; may be
259 * <code>null</code>
260 */
261 public void setPassword(final String password) {
262 assertNotNull(this.release);
263 final Package pkg = this.release.getPackage();
264 assertNotNull(pkg);
265 final Project project = pkg.getProject();
266 assertNotNull(project);
267 final Administrator admin = project.getAdministrator();
268 assertNotNull(admin);
269 this.log("Setting password: " + password);
270 admin.setPassword(password);
271 }
272
273 /***
274 * Called when the <code>releasedate</code> XML attribute is encountered.
275 * Sets the {@linkplain FileRelease#setReleaseDate(Date) release date for the
276 * <code>FileRelease</code>} that will be published.
277 *
278 * @param date
279 * the new release {@link Date}; may be <code>null</code> in
280 * which case the current {@link Date} will be used instead
281 */
282 public void setReleaseDate(final Date date) {
283 assertNotNull(this.release);
284 final Date actualDate;
285 if (date == null) {
286 actualDate = new Date();
287 } else {
288 actualDate = date;
289 }
290 this.log("Setting releasedate: " + actualDate);
291 this.release.setReleaseDate(actualDate);
292 }
293
294 /***
295 * Called when the <code>notify</code> XML attribute is encountered. Sets
296 * whether <a href="http://sourceforge.net/">SourceForge</a> users are
297 * notified when the {@link FileRelease} to be published actually is
298 * published.
299 *
300 * @param notify
301 * if <code>true</code>, then <a
302 * href="http://sourceforge.net/">SourceForge</a> users will be
303 * notified when the {@link FileRelease} to be published
304 * actually is published
305 */
306 public void setNotify(final boolean notify) {
307 assertNotNull(this.release);
308 this.log("Setting notify: " + notify);
309 this.release.setNotifyOthers(notify);
310 }
311
312 /***
313 * Called when the <code>changelog</code> XML attribute is encountered. Sets
314 * the changelog {@link File} associated with the {@link FileRelease} to be
315 * published.
316 *
317 * @param changeLogFile
318 * the changelog {@link File} to be associated with the {@link
319 * FileRelease} to be published; may be <code>null</code>
320 */
321 public void setChangeLog(final File changeLogFile) {
322 assertNotNull(this.release);
323 this.log("Setting changelog: " + changeLogFile);
324 this.release.setChangeLogFile(changeLogFile);
325 }
326
327 /***
328 * Called when the <code>releasenotes</code> XML attribute is encountered.
329 * Sets the release notes {@link File} associated with the {@link FileRelease}
330 * to be published.
331 *
332 * @param releaseNotesFile
333 * the release notes {@link File} to be associated with the
334 * {@link FileRelease} to be published; may be <code>null</code>
335 */
336 public void setReleaseNotes(final File releaseNotesFile) {
337 assertNotNull(this.release);
338 this.log("Setting releasenotes: " + releaseNotesFile);
339 this.release.setReleaseNotesFile(releaseNotesFile);
340 }
341
342 /***
343 * Called when a nested <code>filespec</code> XML element is encountered.
344 * Creates a new, unconfigured {@link FileSpec} object. This method never
345 * returns <code>null</code>.
346 *
347 * @return a new {@link FileSpec} object; never <code>null</code>
348 */
349 public FileSpec createFilespec() {
350 final FileSpec spec = new FileSpec();
351 this.fileSpecs.addElement(spec);
352 return spec;
353 }
354
355 /***
356 * Ensures that the supplied {@link Administrator} is not <code>null</code>.
357 *
358 * @param admin
359 * the {@link Administrator} to test; may be <code>null</code>
360 * in which case a {@link BuildException} will be thrown
361 * @exception BuildException
362 * if the supplied {@link Administrator} is <code>null</code>
363 */
364 private static final void assertNotNull(final Administrator admin)
365 throws BuildException {
366 if (admin == null) {
367 throw new BuildException("admin == null");
368 }
369 }
370
371 /***
372 * Ensures that the supplied {@link Project} is not <code>null</code>.
373 *
374 * @param project
375 * the {@link Project} to test; may be <code>null</code> in
376 * which case a {@link BuildException} will be thrown
377 * @exception BuildException
378 * if the supplied {@link Project} is <code>null</code>
379 */
380 private static final void assertNotNull(final Project project)
381 throws BuildException {
382 if (project == null) {
383 throw new BuildException("project == null");
384 }
385 }
386
387 /***
388 * Ensures that the supplied {@link Package} is not <code>null</code>.
389 *
390 * @param pkg
391 * the {@link Package} to test; may be <code>null</code> in
392 * which case a {@link BuildException} will be thrown
393 * @exception BuildException
394 * if the supplied {@link Package} is <code>null</code>
395 */
396 private static final void assertNotNull(final Package pkg)
397 throws BuildException {
398 if (pkg == null) {
399 throw new BuildException("pkg == null");
400 }
401 }
402
403 /***
404 * Ensures that the supplied {@link FileRelease} is not <code>null</code>.
405 *
406 * @param release
407 * the {@link FileRelease} to test; may be <code>null</code> in
408 * which case a {@link BuildException} will be thrown
409 * @exception BuildException
410 * if the supplied {@link FileRelease} is <code>null</code>
411 */
412 private static final void assertNotNull(final FileRelease release)
413 throws BuildException {
414 if (release == null) {
415 throw new BuildException("release == null");
416 }
417 }
418
419 /***
420 * Called by the <a href="http://ant.apache.org/">Ant</a> framework to execute
421 * this {@link SourceForgePublish} {@link Task}. {@linkplain
422 * FileRelease#publish() Publishes} the {@link FileRelease} that has been
423 * configured behind the scenes by this task.
424 *
425 * @exception BuildException
426 * if an error occurs
427 */
428 public void execute() throws BuildException {
429
430
431
432 final Vector specs = new Vector();
433 final Enumeration e = this.fileSpecs.elements();
434 if (e != null) {
435 FileSpec fileSpec;
436 FileSpecification spec;
437 while (e.hasMoreElements()) {
438 try {
439 fileSpec = (FileSpec)e.nextElement();
440 if (fileSpec == null) {
441 continue;
442 }
443 } catch (final NoSuchElementException ignore) {
444 continue;
445 } catch (final ClassCastException wontHappen) {
446 continue;
447 }
448 spec = fileSpec.getFileSpecification();
449 if (spec != null) {
450 specs.addElement(spec);
451 }
452 }
453 final FileSpecification[] specsArray =
454 new FileSpecification[specs.size()];
455 specs.copyInto(specsArray);
456 this.release.setFileSpecifications(specsArray);
457 this.release.setPublisher(new HttpUnitPublisher());
458 try {
459 this.release.publish();
460 } catch (final Exception everything) {
461 throw new BuildException(everything);
462 }
463 }
464 }
465 }