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 }