Home | History | Annotate | Download | only in rss
      1 /*******************************************************************************
      2  * Copyright (c) 2005, 2006 IBM Corporation and others.
      3  * All rights reserved. This program and the accompanying materials
      4  * are made available under the terms of the Eclipse Public License v1.0
      5  * which accompanies this distribution, and is available at
      6  * http://www.eclipse.org/legal/epl-v10.html
      7  *
      8  * Contributors:
      9  *     IBM Corporation - initial API and implementation
     10  *******************************************************************************/
     11 package org.eclipse.releng.services.rss;
     12 
     13 //TODO: enable support for running task on Windows (problems with ssh, scp, cvs)
     14 //TODO: enable support for connecting to Windows server? (`mkdir -p` not supported)
     15 
     16 import java.io.File;
     17 import java.io.FileInputStream;
     18 import java.io.FileNotFoundException;
     19 import java.io.FileOutputStream;
     20 import java.io.IOException;
     21 
     22 import org.apache.tools.ant.BuildException;
     23 import org.apache.tools.ant.Task;
     24 
     25 import org.eclipse.releng.util.rss.Messages;
     26 import org.eclipse.releng.util.rss.RSSFeedUtil;
     27 
     28 /**
     29  * Parameters:
     30  *   debug - more output to console - eg., 0|1|2
     31  *
     32  *   file - path to the XML file that will be published - eg., /path/to/file.to.publish.xml
     33  *
     34  *   cvsExec - path to the executable for cvs, eg., /usr/bin/cvs
     35  *   cvsRoot - cvs root used to commit the file - eg., username@cvsserver:/cvsroot/path
     36  *   cvsPath - cvs module to update - eg., project/news/ (into which builds.xml would go)
     37  *   cvsTemp - path to the temp folder to use for cvs checkout
     38  *
     39  *   scpExec - path to the executable for scp, eg., /usr/bin/scp
     40  *   scpTarget - scp target path for publishing the file - eg., username@server:/path/to/target/file.xml
     41  *
     42  * Optionally, if the target folder might not exist, you can use ssh to create it before scp'ing
     43  *   sshExec - path to the executable for ssh, eg., /usr/bin/ssh
     44  *
     45  * @author nickb
     46  *
     47  */
     48 public class RSSFeedPublisherTask extends Task {
     49 
     50   private int debug = 0;
     51 
     52   private static final String CL = ":"; //$NON-NLS-1$
     53   private static final String FS = File.separator;
     54   private static final String SP = " "; //$NON-NLS-1$
     55 
     56   // default values for optional fields
     57   private static final String DEFAULT_CVSTemp = "/tmp/tmp-RSSFeedPublisherTask"; //$NON-NLS-1$
     58   private static final String DEFAULT_CVSExec = "cvs"; //$NON-NLS-1$
     59   private static final String DEFAULT_SCPExec = "scp"; //$NON-NLS-1$
     60 
     61   private static final RSSFeedUtil util = new RSSFeedUtil();
     62 
     63   //required fields
     64   private File file;
     65 
     66   // required if doing CVS
     67   private String CVSExec;
     68   private String CVSRoot;
     69   private String CVSPath;
     70   private String CVSTemp;
     71 
     72   // required if doing SCP
     73   private String SCPExec;
     74   private String SCPTarget;
     75 
     76   // required if doing SCP and target dir may not already exist
     77   private String SSHExec;
     78 
     79   //optional
     80   public void setDebug(int debug) { this.debug = debug; }
     81 
     82   //required
     83   public void setFile(String file) {
     84     if (!isNullString(file)) { this.file = new File(file); }
     85   }
     86 
     87   //required for CVS commit (with default)
     88   public void setCVSExec(String CVSExec) {
     89     if (!isNullString(CVSExec)) {
     90       this.CVSExec = CVSExec;
     91     } else {
     92       this.CVSExec = DEFAULT_CVSExec;
     93     }
     94   }
     95 
     96   //required for CVS commit
     97   public void setCVSRoot(String CVSRoot) { this.CVSRoot = CVSRoot; }
     98   public void setCVSPath(String CVSPath) { this.CVSPath = CVSPath; }
     99 
    100   //required for CVS commit (with default)
    101   public void setCVSTemp(String CVSTemp) {
    102     if (!isNullString(CVSTemp)) {
    103       this.CVSTemp = CVSTemp;
    104     } else {
    105       this.CVSTemp = DEFAULT_CVSTemp;
    106     }
    107   }
    108 
    109   //required for CVS commit (with default)
    110   public void setSCPExec(String SCPExec) {
    111     if (!isNullString(SCPExec)) {
    112       this.SCPExec = SCPExec;
    113     } else {
    114       this.SCPExec = DEFAULT_SCPExec;
    115     }
    116   }
    117   public void setSCPTarget(String SCPTarget) { this.SCPTarget = SCPTarget; }
    118 
    119   // required if doing SCP and target dir may not already exist (with default, not assigned)
    120   public void setSSHExec(String SSHExec) {
    121       this.SSHExec = SSHExec;
    122   }
    123 
    124   // The method executing the task
    125   public void execute() throws BuildException {
    126 
    127     if (file==null || !file.exists() || !file.isFile()) {
    128       System.err.println(Messages.getString("RSSFeedPublisherTask.ErrorInvalidFile") + CL + SP + file + "!"); //$NON-NLS-1$ //$NON-NLS-2$
    129     } else {
    130       if (debug>0) { System.out.println(Messages.getString("RSSFeedPublisherTask.Publish") + SP + file); } //$NON-NLS-1$
    131       if ((!isNullString(CVSRoot) && !isNullString(CVSPath)) || !isNullString(SCPTarget)) {
    132         if ((!isNullString(CVSRoot) && !isNullString(CVSPath))) {
    133           commitFeedToCVS();
    134         }
    135         if (!isNullString(SCPTarget)) {
    136           publishFeedWithSCP();
    137         }
    138       } else {
    139         System.err.println(Messages.getString("RSSFeedPublisherTask.ErrorNothingToDo")); //$NON-NLS-1$
    140       }
    141     }
    142   }
    143 
    144   private void commitFeedToCVS()
    145   {
    146     if (debug>1) {
    147       System.out.println(Messages.getString("RSSFeedPublisherTask.UsingCVSRoot") + SP + CVSRoot); //$NON-NLS-1$
    148       System.out.println(Messages.getString("RSSFeedPublisherTask.UsingCVSPath") + SP + CVSPath); //$NON-NLS-1$
    149     }
    150 //  <!-- 3. get filename (eg., builds.xml) from file (which could include a path, eg. ./data/news/builds.xml) -->
    151 //  <pathconvert property="filename"><path path="${file}"/><mapper type="flatten"/></pathconvert>
    152     String filename = file.getName();
    153 
    154 //  <!-- 4. create target temp folder & check out existing version from CVS -->
    155 //  <mkdir dir="${cvsTemp}"/>
    156     File CVSTempDir = new File(CVSTemp);
    157     if (CVSTempDir.isFile()) { // if dir exists as a file, we need a new tmp folder name
    158       CVSTemp += ".tmp";  //$NON-NLS-1$
    159       CVSTempDir = new File(CVSTemp);
    160     }
    161     if (CVSTempDir.isDirectory()) {
    162       if (!CVSTempDir.delete()) {
    163         System.err.println(Messages.getString("RSSFeedPublisherTask.ErrorCouldNotDeleteTempFolder") + SP + CVSTempDir); //$NON-NLS-1$
    164       }
    165     }
    166     CVSTempDir.mkdir();
    167     if (debug>1) {
    168       System.out.println(Messages.getString("RSSFeedPublisherTask.UsingCVSTemp") + SP + CVSTempDir); //$NON-NLS-1$
    169     }
    170 
    171 //  <exec executable="${cvsExec}" dir="${cvsTemp}"><arg line="-d ${cvsRoot} co -d checkoutDir ${cvsPath}"/></exec>
    172     runCVSExecTask("co -d checkoutDir" + SP + CVSPath, CVSTemp); //$NON-NLS-1$
    173 
    174 //  <!-- 5. check if the file already exists in CVS to see if we need to add it -->
    175 //  <available file="${cvsTemp}/checkoutDir/${filename}" type="file" property="fileInCVS"/>
    176     File destFile = new File(CVSTemp + FS + "checkoutDir" + FS + filename); //$NON-NLS-1$
    177     boolean fileInCVS = destFile.isFile();
    178 
    179 //  <!-- 6. overwrite CVS copy with new version; or if new, copy file to destination for add then check-in -->
    180 //  <copy file="../${file}" overwrite="true" todir="${cvsTemp}/checkoutDir"/>
    181     try
    182     {
    183       RSSFeedUtil.transferData(new FileInputStream(file),new FileOutputStream(destFile));
    184     }
    185     catch (FileNotFoundException e)
    186     {
    187       e.printStackTrace();
    188     }
    189     catch (IOException e)
    190     {
    191       e.printStackTrace();
    192     }
    193 
    194 //  <!-- 7. add to CVS (if new) -->
    195 //  <antcall target="addFileToCVS"/>
    196 //  <!-- 7. Add file to CVS (if file is new) -->
    197 //  <target name="addFileToCVS" depends="init" unless="fileInCVS" description="Add file to CVS (if file is new)">
    198 //  <exec executable="${cvsExec}" dir="${cvsTemp}/checkoutDir"><arg line="-d ${cvsRoot} add ${filename}"/></exec>
    199 //  </target>
    200     if (!fileInCVS) {
    201       runCVSExecTask("add " + filename, CVSTemp + FS + "checkoutDir");  //$NON-NLS-1$ //$NON-NLS-2$
    202     }
    203 
    204 //  <!-- 8. check in file -->
    205 //  <exec executable="${cvsExec}" dir="${cvsTemp}/checkoutDir"><arg line="-d ${cvsRoot} ci -m '' ${filename}"/></exec>
    206     runCVSExecTask("ci -m '' " + filename, CVSTemp + FS + "checkoutDir"); //$NON-NLS-1$ //$NON-NLS-2$
    207   }
    208 
    209   private void publishFeedWithSCP()
    210   {
    211     if (debug>1) {
    212       System.out.println(Messages.getString("RSSFeedPublisherTask.PublishToSCPTarget") + SP + SCPTarget); //$NON-NLS-1$
    213     }
    214 
    215 //    <exec executable="${sshExec}"><arg line="${sshMakeDirCommand}"/></exec>
    216     if (!isNullString(SSHExec) && SCPTarget.indexOf(CL)>0) {
    217       String userAtHost = SCPTarget.substring(0, SCPTarget.indexOf(CL));
    218       String targetPath = SCPTarget.substring(SCPTarget.indexOf(CL)+1,SCPTarget.lastIndexOf(FS));
    219       util.runExecTask(SSHExec, userAtHost + " \"mkdir -p" + SP + targetPath + "\"", null); //$NON-NLS-1$ //$NON-NLS-2$
    220     }
    221 
    222 //    <exec executable="${scpExec}" dir="../"><arg line="${file} ${scpTarget}"/></exec>
    223     util.runExecTask(SCPExec, file.toString() + SP + SCPTarget, null);
    224   }
    225 
    226   private void runCVSExecTask(String task, String dir)
    227   {
    228     util.runExecTask(CVSExec, "-d " + CVSRoot + " -q " + task, dir); //$NON-NLS-1$ //$NON-NLS-2$
    229   }
    230 
    231   private static boolean isNullString(String str)
    232   {
    233     return RSSFeedUtil.isNullString(str);
    234   }
    235 
    236 }