1 /**
2 * Copyright 2005-2006 the original author or authors.
3 *
4 * Licensed under the Gnu General Pubic License, Version 2.0 (the
5 * "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.opensource.org/licenses/gpl-license.php
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the Gnu General Public License for more details.
14 */
15 package org.figure8.join.services.vcs;
16
17 import org.figure8.join.util.CVSCrypt;
18 import org.figure8.join.util.LogUtil;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.tools.ant.Project;
22 import org.apache.tools.ant.types.Environment;
23 import org.apache.tools.ant.types.Commandline;
24 import org.apache.tools.ant.taskdefs.Execute;
25
26 import java.io.File;
27 import java.io.FileReader;
28 import java.io.FileWriter;
29 import java.io.PrintWriter;
30 import java.io.BufferedReader;
31 /**
32 * Implementation of <code>VCSAccessor</code> for CVS system. This implementation
33 * uses the cvs.exe client configured on the execution machine. This later should
34 * be in the PATH environment variable (or equivalent).
35 * @author <a href="mailto:laurent.broudoux@free.fr">Laurent Broudoux</a>
36 * @version $Revision: 1.3 $
37 */
38 public class CVSAccessor extends AbstractVCSAccessor{
39
40
41
42 /** Get a commons logger */
43 private static final Log log = LogUtil.getLog(CVSAccessor.class);
44
45 /** Constant for the CVS pserver protocol */
46 public static final String PSERVER_PROTOCOL = "pserver";
47 /** Constant for the CVS checkout command */
48 public static final String CHECKOUT_COMMAND = "checkout";
49
50
51
52
53 /** Creates a new instance of CVSAccessor */
54 public CVSAccessor(){
55
56 setProtocol(PSERVER_PROTOCOL);
57 }
58
59
60
61
62 /**
63 * Login onto configuration management system.
64 * @throws VCSAccessException if login is not successfull
65 */
66 public void login() throws VCSAccessException{
67
68 if (rootRepository == null || rootRepository.length() == 0){
69 log.error("CVS rootRepository must be set to perform login !");
70 throw new VCSAccessException("rootRepository (CVSROOT) must be set to perform login");
71 }
72
73
74 if (protocol == null || protocol.equals(PSERVER_PROTOCOL)){
75 if (password == null){
76 log.error("CVS password must be set when using pserver protocol");
77 throw new VCSAccessException("password must be set when using pserver protocol");
78 }
79
80
81 File passFile = new File(System.getProperty("cygwin.user.home",
82 System.getProperty("user.home")) + File.separatorChar + ".cvspass");
83 if (log.isDebugEnabled())
84 log.debug("CVS password file is " + passFile.getPath());
85
86
87 PrintWriter writer = null;
88 BufferedReader reader = null;
89 try{
90 StringBuffer buffer = new StringBuffer();
91
92
93 if (passFile.exists()){
94 reader = new BufferedReader(new FileReader(passFile));
95
96 String line = null;
97 while ((line = reader.readLine()) != null){
98 if (!line.startsWith(rootRepository))
99 buffer.append(line).append(System.getProperty("line.separator"));
100 }
101 }
102
103 String pwdfile = buffer.toString() + rootRepository + " A" + CVSCrypt.crypt(password);
104 writer = new PrintWriter(new FileWriter(passFile));
105 writer.println(pwdfile);
106 }
107 catch (Exception e){
108
109 log.error("Exception while writing the CVS password file for root " + rootRepository);
110 log.error("The exception message is the following: " + e.getMessage());
111 throw new VCSAccessException("Exception while writing the CVS password file.", e);
112 }
113 finally{
114
115 try {reader.close();}
116 catch (Exception e){
117
118 }
119 try {writer.close();}
120 catch (Exception e){
121
122 log.error("IOException while closing writer for CVS password file for root " + rootRepository);
123 throw new VCSAccessException("IOException while closing CVS password file");
124 }
125 }
126 }
127 }
128
129 /**
130 * Perform a checkout command (or equivalent) on the VCS using a specified
131 * baseline <b>tag</b>. Extracted files are stored within <b>destDirectory</b>
132 * @param tag Baseline tag for retrieving module from VCS
133 * @param destDirectory Path of the destination directory where to put extracted files
134 * @throws VCSAccessException if cehckout command is not successfull
135 */
136 public void checkout(String tag, String destDirectory) throws VCSAccessException{
137 if (log.isInfoEnabled()){
138 log.info("Performing checkout command on CVS repository: '" + rootRepository + "'");
139 log.info("Tag to retrieve on module '" + module + "' is " + tag);
140 }
141
142
143 Commandline c = new Commandline();
144 c.setExecutable("cvs");
145 c.createArgument(true).setLine(CHECKOUT_COMMAND);
146
147
148 if (rootRepository == null || rootRepository.length() == 0){
149 log.error("CVS rootRepository must be set to perform checkout");
150 throw new VCSAccessException("rootRepository (CVSROOT) must be set to perform checkout");
151 }
152
153 c.createArgument(true).setLine("-d" + rootRepository);
154
155
156 if (tag != null && tag.length() > 0)
157 c.createArgument().setLine("-r" + tag);
158
159
160 if (module != null && module.length() > 0)
161 c.createArgument().setLine(module);
162
163
164 if (destDirectory == null || destDirectory.length() == 0){
165 log.error("CVS destDirectory must be set to perform checkout");
166 throw new VCSAccessException("destDirectory must be set to perform checkout");
167 }
168 File dest = new File(destDirectory);
169 if (!dest.isDirectory()){
170 try {dest.mkdirs();}
171 catch (Exception e){
172 throw new VCSAccessException("IOException while creating destination directory");
173 }
174 }
175
176
177 Environment env = new Environment();
178
179 File passFile = new File(System.getProperty("cygwin.user.home",
180 System.getProperty("user.home")) + File.separatorChar + ".cvspass");
181 Environment.Variable var = new Environment.Variable();
182 var.setKey("CVS_PASSFILE");
183 var.setValue(String.valueOf(passFile));
184 env.addVariable(var);
185
186
187 Execute exe = new Execute(getExecuteStreamHandler(), null);
188 exe.setAntRun(new Project());
189 exe.setWorkingDirectory(dest);
190 exe.setCommandline(c.getCommandline());
191 exe.setEnvironment(env.getVariables());
192
193 int returnCode = -1;
194
195 try{
196 if (log.isDebugEnabled())
197 log.debug("Checkout command line is: " + c.getCommandline());
198
199 returnCode = exe.execute();
200 }
201 catch (Exception e){
202 log.error("CVS checkout execution on '" + rootRepository + "' throws an exception");
203 log.error("Here's the exception message: " + e.getMessage());
204 throw new VCSAccessException("Exception during checkout command on '" + rootRepository + "': " + e.getMessage());
205 }
206
207 log.info("CVS checkout return code is: " + returnCode);
208
209 if (returnCode != 0)
210 throw new VCSAccessException("CVS ckeckout command return abnormally ...");
211 }
212
213 /**
214 * Logout from configuration management system.
215 * @throws VCSAccessException if logout is not successfull
216 */
217 public void logout() throws VCSAccessException{
218
219 }
220 }