View Javadoc

1   /*
2    * Maven SourceForge plugin 
3    * Author: Ludovic Claude (ludovicc@users.sourceforge.net)
4    * Distributable under BSD license.
5    */
6   
7   package net.sourceforge.mavenplugins.sourceforge;
8   
9   import java.io.BufferedReader;
10  import java.io.File;
11  import java.io.FileReader;
12  import java.io.LineNumberReader;
13  import java.text.DateFormat;
14  import java.text.SimpleDateFormat;
15  import java.util.Date;
16  import java.util.Iterator;
17  
18  import org.apache.commons.httpclient.URIException;
19  import org.apache.commons.httpclient.methods.GetMethod;
20  import org.apache.commons.httpclient.methods.MultipartPostMethod;
21  import org.apache.commons.httpclient.methods.PostMethod;
22  import org.apache.commons.jelly.JellyTagException;
23  import org.apache.commons.jelly.MissingAttributeException;
24  import org.apache.commons.jelly.TagSupport;
25  import org.apache.commons.jelly.XMLOutput;
26  import org.apache.commons.jxpath.JXPathContext;
27  import org.apache.commons.jxpath.Pointer;
28  import org.w3c.dom.Document;
29  
30  /***
31   * Bean used for accessing the File Release System on Sourceforge.
32   * 
33   * @author <a href="mailto:ludovicc@users.sourceforge.net">Ludovic Claude</a>
34   * @author Stephen Colebourne
35   * @version $Revision: 1.10 $ $Date: 2006/01/07 22:50:45 $
36   * @created on 5 dec. 2003
37   */
38  public class FileReleaseSystemBean extends TagSupport {
39  
40      private static final String RELEASE_STATUS_ACTIVE = "1";
41      //private static final String RELEASE_STATUS_HIDDEN = "3";
42  
43      private WebBrowser _browser;
44      private String _srcDir;
45      private int _sfGroupId;
46      private String _sfUserName;
47      private String _sfPassword;
48      privateong> String _package;
49      private String _release;
50      private boolean _overwriteRelease;
51      private File _changeLogFile;
52      private File _releaseNotesFile;
53      private String _proxyHost;
54      private int _proxyPort;
55      private String _proxyUserName;
56      private String _proxyPassword;
57      private String _proxyNTDomain;
58      private boolean _submitNewsItem;
59      private String _newsTitle;
60      private String _projectName;
61      private boolean _sendEmailNotice;
62  
63      /***
64       * Constructor for FileReleaseSystemBean
65       */
66      public FileReleaseSystemBean() {
67          super();
68          _browser = WebBrowser.getInstance();
69      }
70  
71      /***
72       * Gets the srcDir.
73       * @return the srcDir.
74       */
75      public String getSrcDir() {
76          return _srcDir;
77      }
78  
79      /***
80       * Sets the srcDir.
81       * @param srcDir The srcDir to set.
82       */
83      public void setSrcDir(String srcDir) {
84          _srcDir = srcDir;
85      }
86      
87      /***
88       * Gets the sfGroupId.
89       * @return the sfGroupId.
90       */
91      public int getSfGroupId() {
92          return _sfGroupId;
93      }
94  
95      /***
96       * Sets the sfGroupId.
97       * @param sfGroupId The sfGroupId to set.
98       */
99      public void setSfGroupId(int sfGroupId) {
100         _sfGroupId = sfGroupId;
101     }
102 
103     /***
104      * Gets the sfUserName.
105      * @return the sfUserName.
106      */
107     public String getSfUserName() {
108         return _sfUserName;
109     }
110 
111     /***
112      * Sets the sfUserName.
113      * @param sfUserName The sfUserName to set.
114      */
115     public void setSfUserName(String sfUserName) {
116         _sfUserName = sfUserName;
117     }
118 
119     /***
120      * Gets the sfPassword.
121      * @return the sfPassword.
122      */
123     public String getSfPassword() {
124         return _sfPassword;
125     }
126 
127     /***
128      * Sets the sfPassword.
129      * @param sfPassword The sfPassword to set.
130      */
131     public void setSfPassword(String sfPassword) {
132         _sfPassword = sfPassword;
133     }
134 
135     /***
136      * Returns the project name
137      * @return the project name
138      */
139     public String getProjectName() {
140         return _projectName;
141     }
142     
143     /***
144      * Sets the project name
145      * @param name The name
146      */
147     public void setProjectName(String name) {
148         _projectName = name;
149     }
150     
151     /***
152      * Gets the package.
153      * @return the package.
154      */
155     public String getPackage() {
156         return</strong> _package;
157     }
158 
159     /***
160      * Sets the package.
161      * @param package1 The package to set.
162      */
163     publicong> void setPackage(String package1) {
164         _package</strong> = package1;
165     }
166 
167     /***
168      * Gets the release.
169      * @return the release.
170      */
171     public String getRelease() {
172         return _release;
173     }
174 
175     /***
176      * Sets the release.
177      * @param release The release to set.
178      */
179     public void setRelease(String release) {
180         _release = release;
181     }
182 
183     /***
184      * Gets the overwriteRelease flag.
185      * @return the overwriteRelease flag.
186      */
187     public boolean isOverwriteExistingRelease() {
188         return _overwriteRelease;
189     }
190 
191     /***
192      * Sets the overwriteRelease flag.
193      * @param overwrite The overwriteRelease flag.
194      */
195     public void setOverwriteExistingRelease(boolean overwrite) {
196         _overwriteRelease = overwrite;
197     }
198 
199     /***
200      * Gets the changeLogFile.
201      * @return the changeLogFile.
202      */
203     public File getChangeLogFile() {
204         return _changeLogFile;
205     }
206 
207     /***
208      * Sets the changeLogFile.
209      * @param changeLogFile The changeLogFile to set.
210      */
211     public void setChangeLogFile(File changeLogFile) {
212         _changeLogFile = changeLogFile;
213     }
214 
215     /***
216      * Gets the releaseNotesFile.
217      * @return the releaseNotesFile.
218      */
219     public File getReleaseNotesFile() {
220         return _releaseNotesFile;
221     }
222 
223     /***
224      * Sets the releaseNotesFile.
225      * @param releaseNotesFile The releaseNotesFile to set.
226      */
227     public void setReleaseNotesFile(File releaseNotesFile) {
228         _releaseNotesFile = releaseNotesFile;
229     }
230 
231     /***
232      * Gets the submitNewsItem.
233      * @return the submitNewsItem.
234      */
235     public boolean isSubmitNewsItem() {
236         return _submitNewsItem;
237     }
238 
239     /***
240      * Sets the sendEmailNotice.
241      * @param sendEmailNotice The sendEmailNotice to set.
242      */
243     public void setSendEmailNotice(boolean sendEmailNotice) {
244         _sendEmailNotice = sendEmailNotice;
245     }
246 
247     /***
248      * Gets the sendEmailNotice.
249      * @return the sendEmailNotice.
250      */
251     public boolean isSendEmailNotice() {
252         return _sendEmailNotice;
253     }
254 
255     /***
256      * Sets the submitNewsItem.
257      * @param submitNewsItem The submitNewsItem to set.
258      */
259     public void setSubmitNewsItem(boolean submitNewsItem) {
260         _submitNewsItem = submitNewsItem;
261     }
262 
263     /***
264      * Gets the newsTitle.
265      * @return the newsTitle.
266      */
267     public String getNewsTitle() {
268         return _newsTitle;
269     }
270 
271     /***
272      * Sets the newsTitle.
273      * @param newsTitle The newsTitle to set.
274      */
275     public void setNewsTitle(String newsTitle) {
276         _newsTitle = newsTitle;
277     }
278 
279     /***
280      * Gets the proxyHost.
281      * @return the proxyHost.
282      */
283     public String getProxyHost() {
284         return _proxyHost;
285     }
286 
287     /***
288      * Sets the proxyHost.
289      * @param proxyHost The proxyHost to set.
290      */
291     public void setProxyHost(String proxyHost) {
292         _proxyHost = proxyHost;
293     }
294 
295     /***
296      * Gets the proxyPort.
297      * @return the proxyPort.
298      */
299     public int getProxyPort() {
300         return _proxyPort;
301     }
302 
303     /***
304      * Sets the proxyPort.
305      * @param proxyPort The proxyPort to set.
306      */
307     public void setProxyPort(int proxyPort) {
308         _proxyPort = proxyPort;
309     }
310 
311     /***
312      * Gets the proxyUserName.
313      * @return the proxyUserName.
314      */
315     public String getProxyUserName() {
316         return _proxyUserName;
317     }
318 
319     /***
320      * Sets the proxyUserName.
321      * @param proxyUserName The proxyUserName to set.
322      */
323     public void setProxyUserName(String proxyUserName) {
324         _proxyUserName = proxyUserName;
325     }
326     
327     /***
328      * Gets the proxyPassword.
329      * @return the proxyPassword.
330      */
331     public String getProxyPassword() {
332         return _proxyPassword;
333     }
334 
335     /***
336      * Sets the proxyPassword.
337      * @param proxyPassword The proxyPassword to set.
338      */
339     public void setProxyPassword(String proxyPassword) {
340         _proxyPassword = proxyPassword;
341     }
342 
343     /***
344      * Gets the proxyNTDomain.
345      * @return the proxyNTDomain.
346      */
347     public String getProxyNTDomain() {
348         return _proxyNTDomain;
349     }
350 
351     /***
352      * Sets the proxyNTDomain.
353      * @param proxyNTDomain The proxyNTDomain to set.
354      */
355     public void setProxyNTDomain(String proxyNTDomain) {
356         _proxyNTDomain = proxyNTDomain;
357     }
358 
359     public void execute() throws Exception {
360         try {
361 //            System.out.println(getSfUserName());
362 //            System.out.println(getSfPassword());
363 //            System.out.println(getSrcDir());
364 //            System.out.println(getChangeLogFile());
365 //            System.out.println(getReleaseNotesFile());
366 //            System.out.println(getProjectName());
367 //            System.out.println(getSfGroupId());
368 //            System.out.println(getPackage());
369 //            System.out.println(getPackageDescription());
370 //            System.out.println(getRelease());
371 //            System.out.println(isOverwriteExistingRelease());
372 //            System.out.println(isSendEmailNotice());
373 //            System.out.println(isSubmitNewsItem());
374             
375             // Sanity check
376             if (_srcDir == null) {
377                 throw new Exception("Src dir is not defined. Check that property maven.sourceforge.publishDir is set");
378             }
379             if (_projectName == null && _sfGroupId <= 0) {
380                 throw new Exception("Invalid projectName/groupId parameter: check that property maven.sourceforge.project.projectName or maven.sourceforge.project.groupId is not empty");
381             }
382             >if (_package == null || _package.trim().length() == 0) {
383                 throw new Exception("Invalid package parameter: check that property maven.sourceforge.project.packageName is not empty");
384             }
385             if (_release == null || _release.trim().length() == 0) {
386                 throw new Exception("Invalid release parameter: check that property maven.sourceforge.project.version is not empty");
387             }
388             if (_proxyHost != null && _proxyHost.trim().length() != 0) {
389                 _browser.useProxy(_proxyHost, _proxyPort, _proxyUserName, _proxyPassword, _proxyNTDomain);
390             }
391             // Login to sourceforge Website 
392             System.out.println("Logging on " + _sfUserName);
393             login();
394             System.out.println("Logged on");
395             GetMethod getMethod;
396             Document doc;
397             // Detect group id if user didn't set it
398             if (_sfGroupId <= 0) {
399                 getMethod = new GetMethod("https://sourceforge.net/projects/" + _projectName);
400                 doc = _browser.getDocument(getMethod);
401                 _sfGroupId = getGroupId(doc);
402             } else {
403                 System.out.println("Using group id " + _sfGroupId);
404             }
405             // Go to the File Releases page 
406             getMethod = new GetMethod("https://sourceforge.net/project/admin/editpackages.php?group_id=" + _sfGroupId);
407             doc = _browser.getDocument(getMethod);
408             if (isReleasePermissionDenied(doc)) {
409                 throw new Exception("You don't have permission to release files for group " + _sfGroupId);
410             }
411             // Get the package id, or create it if it doesn't exists
412             int packageId = getPackageId(doc);
413             >if (packageId == -1) {
414                 if (!canCreatePackage(doc)) {
415                     throw new Exception("You don't have any rights to create a new package called " + _package 
416                             + ", set the property maven.sourceforge.project.packageName with the name of an existing package");
417                 }
418                 packageId = createPackage();
419             }
420             >if (packageId == -1) {
421                 throw new Exception("Could not create package " + _package + " for project #" + _sfGroupId);
422             }
423             // Get the release id, or create it if it doesn't exists
424             getMethod = new GetMethod("http://sourceforge.net/project/admin/editreleases.php?package_id=" + packageId 
425                     + "&group_id=" + _sfGroupId);
426             doc = _browser.getDocument(getMethod);
427             int releaseId = getReleaseId(doc);
428             if (releaseId == -1) {
429                 releaseId = createRelease(packageId);
430             } else {
431                 if (isOverwriteExistingRelease() == false) {
432                     throw new Exception("Not permitted to overwrite release " + _release + " for package " + _package + " as maven.sourceforge.overwriteExistingVersion=false");
433                 }
434             }
435             if (releaseId == -1) {
436                 throw new Exception("Could not create release " + _release + " for package " + _package);
437             }
438             // Upload changelog and release notes
439             doc = uploadNotes(packageId, releaseId);
440             // Selected our uploaded files
441             doc = selectUploadedFiles(packageId, releaseId);
442             // Define the plateform support and the file type for each files
443             File sourceDir = new File(_srcDir);
444             File[] files = sourceDir.listFiles();
445 
446             for (int i = 0; i < files.length; i++) {
447                 File file = files[i];
448                 String fileName = file.getName();
449                 System.out.println("Defining file information for file " + fileName);
450                 int fileId = getFileId(doc, fileName);
451                 doc = defineFileInformation(packageId, releaseId, fileId, fileName);
452             }
453             // Send email notification 
454             if (isSendEmailNotice()) {
455                 sendEmailConfirmation(packageId, releaseId);
456             } else {
457                 System.out.println("Release email NOT sent - maven.sourceforge.project.sendEmailNotice=false");
458             }
459             // Submit a news item about the release
460             if (isSubmitNewsItem()) {
461                 submitNewsItem();
462             } else {
463                 System.out.println("Release news item NOT sent - maven.sourceforge.project.submitNewsItem=false");
464             }
465         } catch (Exception ex) {
466             ex.printStackTrace();
467             throw ex;
468         }
469     }
470     
471     /*** 
472      * {@inheritDoc}
473      */
474     public void doTag(XMLOutput out) throws MissingAttributeException, JellyTagException {
475         try {
476             execute();
477         } catch (Exception e) {
478             throw new JellyTagException(e);
479         }
480     }
481 
482     protected void login() throws Exception {
483         GetMethod getMethod = new GetMethod("https://sourceforge.net/account/login.php");
484         Document doc = _browser.getDocument(getMethod);
485         
486         PostMethod postMethod = new PostMethod("https://sourceforge.net/account/login.php");
487         postMethod.setFollowRedirects(false);
488         postMethod.addParameter("return_to", "");
489         postMethod.addParameter("form_loginname", _sfUserName);
490         postMethod.addParameter("form_pw", _sfPassword);
491         postMethod.addParameter("login", "Login");
492         
493         doc = _browser.getDocument(postMethod);
494         
495         if (!checkLoginResponse(doc)) {
496             throw new Exception("Could not login in Sourgeforge website with user name " + _sfUserName 
497                     + " and password " + _sfPassword);
498         }
499     }
500 
501     protected boolean checkLoginResponse(Document doc) {
502         try {
503             JXPathContext context = JXPathContext.newContext(doc);
504             context.setLenient(true);
505             
506             Object erreurs = context.getValue("//*[text()='Invalid Password or User Name']");
507 
508             return (erreurs == null);
509         } catch (Exception e) {
510             e.printStackTrace();
511         }
512 
513         return false;
514     }
515 
516     /***
517      * Locates the group id in the page, else returns -1
518      * @param doc The html page Project summary
519      * @return the project group id, or -1
520      */
521     protected int getGroupId(Document doc) {
522         JXPathContext context = JXPathContext.newContext(doc);
523         context.setLenient(true);
524         Iterator i = context.iteratePointers("//a[starts-with(@href, '/project/admin/?group_id=')]");
525         while (i.hasNext()) {
526             Pointer pointer = (Pointer) i.next();
527             JXPathContext nodeContext = context.getRelativeContext(pointer);
528             if (nodeContext.getValue("@href") != null) {
529                 String groupId = (String) nodeContext.getValue("@href");
530                 groupId = groupId.substring("/project/admin/?group_id=".length());
531                 System.out.println("Found group " + _projectName + ", id=" + groupId);
532                 return Integer.parseInt(groupId);
533             }
534         }
535         return -1;
536     }
537     
538     /***
539      * @param doc The html page Admin: FRS: Packages
540      * @return true if the user is denied permission to make releases
541      */
542     protected boolean isReleasePermissionDenied(Document doc) {
543         JXPathContext context = JXPathContext.newContext(doc);
544         context.setLenient(true);
545         Object node = context.getValue("//node()[@class='error' and contains(text(), 'Permission Denied')]");
546         return node != null;
547     }
548     
549     /***
550      * Locates the package id in the page if it exists, else returns -1
551      * @param doc The html page Admin: FRS: Packages
552      * @return the package id, or -1
553      */
554     protected int getPackageId(Document doc) {
555         JXPathContext context = JXPathContext.newContext(doc);
556         context.setLenient(true);
557         Iterator i = context.iteratePointers("//form[@action='/project/admin/editpackages.php']");
558         while (i.hasNext()) {
559             Pointer pointer = (Pointer) i.next();
560             JXPathContext nodeContext = context.getRelativeContext(pointer);
561             if (nodeContext.getValue(".//input[@name='package_name'][@value='" + _package + "']") != null
562                     || nodeContext.getValue(".//text()[.='" + _package + "']") != null) {
563                 String packageId = (String) nodeContext.getValue(".//input[@name='package_id']/@value");
564                 System.out.println("Found package " + _package + ", id=" + packageId);
565                 >return Integer.parseInt(packageId);
566             }
567         }
568         return -1;
569     }
570 
571     /***
572      * @param doc The html page Admin: FRS: Packages
573      * @return true if the user is authorised to add a new package
574      */
575     protected boolean canCreatePackage(Document doc) {
576         JXPathContext context = JXPathContext.newContext(doc);
577         context.setLenient(true);
578         Object node = context.getValue("//input[@name='func'][@value='add_package']");
579         return node != null;
580     }
581     
582     /***
583      * Creates a new package
584      * @return the new package id
585      */
586     protected int createPackage() throws Exception {
587         System.out.println("Creating package " + _package);
588         PostMethod postMethod = new PostMethod("https://sourceforge.net/project/admin/editpackages.php");
589 
590         postMethod.setFollowRedirects(true);
591         postMethod.addParameter("group_id", String.valueOf(_sfGroupId));
592         postMethod.addParameter("func", "add_package");
593         postMethod.addParameter("package_name", _package);
594         
595         Document doc = _browser.getDocument(postMethod);
596         return getPackageId(doc);
597     }
598 
599     /***
600      * Locates the release id in he page if it exists, else returns -1
601      * @param doc The html page Admin: FRS: Releases
602      * @return the release id, or -1
603      */
604     protected int getReleaseId(Document doc) {
605         JXPathContext context = JXPathContext.newContext(doc);
606         context.setLenient(true);
607         Iterator i = context.iteratePointers("//table/tr/td[1]/font[starts-with(a/@href, 'editreleases.php?')]");
608         while (i.hasNext()) {
609             Pointer pointer = (Pointer) i.next();
610             JXPathContext nodeContext = context.getRelativeContext(pointer);
611             String textValue = (String) nodeContext.getValue("text()");
612             if (textValue == null) {
613                 continue;
614             }
615             textValue = textValue.trim();
616             if (_release.equals(textValue)) {
617                 String href = (String) nodeContext.getValue("a/@href");
618                 int pos = href.indexOf("release_id=") + "release_id=".length();
619                 String releaseId = href.substring(pos);
620                 pos = releaseId.indexOf('&');
621                 if (pos >= 0) {
622                     releaseId = releaseId.substring(0, pos);
623                 }
624                 System.out.println("Found release " + _release + " for package " + _package + ", id=" + releaseId);
625                 return Integer.parseInt(releaseId);
626             }
627         }
628         return -1;
629     }
630 
631     /***
632      * Creates a new release for the package
633      * @return the release id, or -1 if the release could notbe created
634      */
635     protectedong> int createRelease(int packageId) throws Exception {
636         System.out.println("Creating release " + _release + " for package " + _package);
637         GetMethod getMethod = new GetMethod("http://sourceforge.net/project/admin/newrelease.php?packageId=" 
638                 + packageId + "&group_id=" + _sfGroupId);
639         Document doc = _browser.getDocument(getMethod);
640         
641         PostMethod postMethod = new PostMethod("http://sourceforge.net/project/admin/newrelease.php");
642         postMethod.addParameter("group_id", String.valueOf(_sfGroupId));
643         postMethod.addParameter("newrelease", "yes");
644         postMethod.addParameter("release_name", _release);
645         postMethod.addParameter("package_id", String.valueOf(packageId));
646         postMethod.addParameter("submit", "Create This Release");
647 
648         doc = _browser.getDocument(postMethod);
649         
650         return getCreatedReleaseId(doc);
651     }
652 
653     protected int getCreatedReleaseId(Document doc) throws NumberFormatException {
654         JXPathContext context = JXPathContext.newContext(doc);
655         context.setLenient(false);
656         String releaseId = (String) context.getValue("//input[@name='release_id']/@value");
657         if (releaseId != null) {
658             System.out.println("Created release " + _release + ", id=" + releaseId);
659             return Integer.parseInt(releaseId);
660         }
661         return -1;
662     }
663 
664     /***
665      * Upload the changes and release notes 
666      * 
667      * @param packageId The package id
668      * @param releaseId The release id
669      * @return the result page
670      */
671     protectedong> Document uploadNotes(int packageId, int releaseId) throws Exception {
672         MultipartPostMethod postMethod = new MultipartPostMethod("https://sourceforge.net/project/admin/editreleases.php");
673         postMethod.addParameter("group_id", String.valueOf(_sfGroupId));
674         postMethod.addParameter("package_id", String.valueOf(packageId));
675         postMethod.addParameter("new_package_id", String.valueOf(packageId));
676         postMethod.addParameter("release_id", String.valueOf(releaseId));
677         postMethod.addParameter("step1", "1");
678         DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
679         postMethod.addParameter("release_date", df.format(new Date()));
680         postMethod.addParameter("release_name", _release);
681         postMethod.addParameter("status_id", RELEASE_STATUS_ACTIVE);
682         if (_releaseNotesFile != null && _releaseNotesFile.exists()) {
683             postMethod.addParameter("uploaded_notes", _releaseNotesFile);
684         }
685         if (_changeLogFile != null && _changeLogFile.exists()) {
686             postMethod.addParameter("uploaded_changes", _changeLogFile);
687         }
688         postMethod.addParameter("preformatted", "1");
689         
690         Document doc = _browser.getDocument(postMethod);
691         System.out.println("Release and change notes uploaded");
692         return doc;
693     }
694     
695     /***
696      * Select our uploaded files to include in the file release page
697      * @param packageId The package id
698      * @param releaseId The release id
699      * @return the result page
700      */
701     protectedong> Document selectUploadedFiles(int packageId, int releaseId) throws Exception {
702         PostMethod postMethod = new PostMethod("https://sourceforge.net/project/admin/editreleases.php");
703         postMethod.addParameter("group_id", String.valueOf(_sfGroupId));
704         postMethod.addParameter("package_id", String.valueOf(packageId));
705         postMethod.addParameter("release_id", String.valueOf(releaseId));
706         postMethod.addParameter("step2", "1");
707         File sourceDir = new File(_srcDir);
708         File[] files = sourceDir.listFiles();
709         if (files == null || files.length == 0) {
710             throw new Exception("No files to upload");
711         }
712         for (int i = 0; i < files.length; i++) {
713             File file = files[i];
714             String fileName = file.getName();
715             postMethod.addParameter("file_list[]", fileName);
716         }
717         
718         Document doc = _browser.getDocument(postMethod);
719         System.out.println("Released files selected");
720         return doc;
721     }
722     
723     /***
724      * Gets the file id for the given file
725      * @param doc The html page Admin: FRS: Releases
726      * @param fileName The file name
727      * @return the file id
728      */
729     protected int getFileId(Document doc, String fileName) throws Exception {
730         JXPathContext context = JXPathContext.newContext(doc);
731         context.setLenient(false);
732         try {
733             Pointer pointer = context.getPointer("//table/form[input/@name = 'step3'][.//font/text() = '" + fileName + "']");
734             JXPathContext nodeContext = context.getRelativeContext(pointer);
735             String fileId = (String) nodeContext.getValue("input[@name = 'file_id']/@value");
736             return Integer.parseInt(fileId);
737         } catch (Exception ex) {
738             ex.printStackTrace();
739             throw new Exception("Cannot locate the file " + fileName + " on the file release page");
740         }
741     }
742     
743     /***
744      * Defines the file information like plateform support and file type
745      * @param packageId The package id
746      * @param releaseId The release id
747      * @param fileId The file id
748      * @param fileName The file name
749      * @return the result page
750      */
751     protectedong> Document defineFileInformation(int packageId, int releaseId, int fileId, String fileName) throws Exception {
752         PostMethod postMethod = new PostMethod("https://sourceforge.net/project/admin/editreleases.php");
753         postMethod.addParameter("group_id", String.valueOf(_sfGroupId));
754         postMethod.addParameter("package_id", String.valueOf(packageId));
755         postMethod.addParameter("release_id", String.valueOf(releaseId));
756         postMethod.addParameter("new_release_id", String.valueOf(releaseId));
757         postMethod.addParameter("file_id", String.valueOf(fileId));
758         postMethod.addParameter("step3", "1");
759         postMethod.addParameter("processor_id", "8500");
760         String type = "3002";
761         if (fileName.endsWith("-src.tar.gz")) {
762             type = "5002";
763         } else if (fileName.endsWith("-src.zip")) {
764             type = "5000";
765         } else if (fileName.endsWith(".gz")) {
766             type = "3002";
767         } else if (fileName.endsWith(".zip")) {
768             type = "3000";
769         } else if (fileName.endsWith(".jar")) {
770             type = "2601";
771         }
772         postMethod.addParameter("type_id", type);
773         postMethod.addParameter("file_id", String.valueOf(fileId));
774         DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
775         postMethod.addParameter("release_time", df.format(new Date()));
776         postMethod.addParameter("submit", "Update/Refresh");
777         
778         return _browser.getDocument(postMethod);
779     }
780 
781     /***
782      * Send the email confirmation to the users monitoring the package
783      * @param packageId The package id
784      * @param releaseId The release id
785      */
786     protectedong> void sendEmailConfirmation(int packageId, int releaseId) throws URIException {
787         System.out.println("Sending confirmation email");
788         PostMethod postMethod = new PostMethod("https://sourceforge.net/project/admin/editreleases.php");
789         postMethod.addParameter("group_id", String.valueOf(_sfGroupId));
790         postMethod.addParameter("package_id", String.valueOf(packageId));
791         postMethod.addParameter("release_id", String.valueOf(releaseId));
792         postMethod.addParameter("step4", "1");
793         postMethod.addParameter("sure", "1");
794         postMethod.addParameter("submit", "Send Notice");
795         
796         _browser.executeMethod(postMethod);
797         System.out.println("Release email sent");
798     }
799 
800     /***
801      * Submit a news item informing users about the release
802      */
803     protected void submitNewsItem() throws Exception {
804         if (_releaseNotesFile == null || !_releaseNotesFile.exists()) {
805             System.out.println("Cannot find the release notes to include in the news item.");
806             return;
807         }
808         System.out.println("Posting news about the release");
809         FileReader reader = new FileReader(_releaseNotesFile);
810         LineNumberReader lr = new LineNumberReader(new BufferedReader(reader));
811         String releaseNotes = ""; 
812         String line = lr.readLine();
813         while (line != null) {
814             releaseNotes += line + "\r\n";
815             line = lr.readLine();
816         }
817         
818         GetMethod getMethod = new GetMethod("https://sourceforge.net/news/submit.php?group_id=" + _sfGroupId);
819         _browser.getDocument(getMethod);
820         
821         PostMethod postMethod = new PostMethod("https://sourceforge.net/news/submit.php");
822 
823         postMethod.setFollowRedirects(false);
824         postMethod.addParameter("Content-Type", "text/html; charset=iso-8859-1");
825         postMethod.addParameter("group_id", String.valueOf(_sfGroupId));
826         postMethod.addParameter("post_changes", "y");
827         postMethod.addParameter("summary", _newsTitle + " " + _release + " released.");
828         postMethod.addParameter("details", releaseNotes);
829         postMethod.addParameter("SUBMIT", "SUBMIT");
830         _browser.executeMethod(postMethod);
831         System.out.println("Release news item sent");
832     }
833 
834 }