001 /*
002 * SvnRepository.java
003 * Copyright (c) 1998-2008, The University of Sheffield.
004 *
005 * This code is from the GATE project (http://gate.ac.uk/) and is free
006 * software licenced under the GNU General Public License version 3. It is
007 * distributed without any warranty. For more details see COPYING.txt in the
008 * top level directory (or at http://gatewiki.sf.net/COPYING.txt).
009 *
010 * Hamish Cunningham 27/Aug/2005
011 */
012
013 package gate.versioning.cmdline;
014 import java.io.*;
015 import java.util.*;
016 import gate.util.*;
017
018 /**
019 * SVN repository implementation.
020 * The public API of this class is documented on the
021 * {@link Repository} interface.
022 * @see gate.versioning.cmdline.Repository
023 */
024 public class SvnRepository extends AbstractRepository {
025
026 /** Debug flag. */
027 private boolean DEBUG = false;
028
029 /** Returns "svn". */
030 public String getCommandName() { return "svn"; }
031
032 /** Get the pre-subcommand elements of the command (e.g. -d root). */
033 protected List getPreCommand() {
034 List preCommand = new ArrayList();
035 return preCommand;
036 } // getPreCommand()
037
038 /** Get the post-subcommand elements of the command (e.g. root). */
039 protected List getPostCommand(String fileName, boolean noRoot) {
040 List postCommand = new ArrayList();
041 if(noRoot) {
042 if(fileName != null)
043 postCommand.add(fileName);
044 } else {
045 if(fileName != null)
046 postCommand.add(root + "/" + fileName);
047 else
048 postCommand.add(root);
049 }
050
051 return postCommand;
052 } // getPostCommand()
053
054 /**
055 * The root / URL of the repository. SVN doesn't like backslash here
056 * (at least on version 1.2.3 Windoze build run from cygwin or via
057 * Runtime.exec), so substitute them all for slash.
058 */
059 public void setRoot(String root) {
060 this.root = root.replaceAll("\\\\", "/");
061 } // setRoot()
062
063 /**
064 * Commit changes.
065 * @param fileName the file or directory to work on (should be relative
066 * to the repository's working directory, and use "/" as a path separator).
067 * @param message a commit message.
068 * @return boolean representing success or failure.
069 */
070 public boolean checkin(String fileName, String message) {
071 String[] com = buildCommandArray(fileName, "ci", "-m" + message, true);
072 return runCommand(com);
073 } // checkin()
074
075 /**
076 * Update.
077 * @param fileName the file or directory to work on (should be relative
078 * to the repository's working directory, and use "/" as a path separator).
079 * @return boolean representing success or failure.
080 */
081 public boolean update(String fileName) {
082 String[] com = buildCommandArray(fileName, "update", null, true);
083 return runCommand(com);
084 } // update()
085
086 /**
087 * Status.
088 * @param fileName the file or directory to work on (should be relative
089 * to the repository's working directory, and use "/" as a path separator).
090 * @return String giving status ouput.
091 */
092 public String status(String fileName) {
093 String[] com = buildCommandArray(
094 fileName, "status", "--show-updates", true
095 );
096 if(! runCommand(com))
097 return null;
098 else
099 return getCommandStdout();
100 } // status()
101
102 /**
103 * Delete from the repository.
104 * @param fileName the file or directory to work on (should be relative
105 * to the repository's working directory, and use "/" as a path separator).
106 * @return boolean representing success or failure.
107 */
108 public boolean delete(String fileName) {
109 String[] com = buildCommandArray(fileName, "delete", null, true);
110 return runCommand(com);
111 } // delete()
112
113 /**
114 * Add to the repository.
115 * @param fileName the file or directory to work on (should be relative
116 * to the repository's working directory, and use "/" as a path separator).
117 * @return boolean representing success or failure.
118 */
119 public boolean add(String fileName) {
120 String[] com = buildCommandArray(fileName, "add", null, true);
121 return runCommand(com);
122 } // add()
123
124 /**
125 * Get the difference with the repository version.
126 * @param fileName the file or directory to work on (should be relative
127 * to the repository's working directory, and use "/" as a path separator).
128 * @return a string containing the difference, or "" for no difference, or
129 * null for error.
130 */
131 public String diff(String fileName) {
132 String[] com = buildCommandArray(fileName, "diff", null, true);
133 if(! runCommand(com, true))
134 return null;
135 return getCommandStdout();
136 } // diff()
137
138 /**
139 * Create a new repository filetree (i.e. not a new object but a new
140 * database/filesystem on disk).
141 * This method can be called before {@link #init} (so that we
142 * can create repositories without having an existing one).
143 * @param dirName the directory to work on, which will be created
144 * (should be an absolute path).
145 * @return boolean representing success or failure.
146 */
147 public boolean create(String dirName) {
148 String[] command = new String[5];
149 command[0] = "svnadmin";
150 command[1] = "create";
151 command[2] = "--fs-type";
152 command[3] = "fsfs";
153 command[4] = dirName;
154
155 boolean result = runCommand(command);
156 return result;
157 } // create()
158
159 /**
160 * Import a directory.
161 * @param dirName the directory to import (this must exist).
162 * @return boolean representing success or failure.
163 * @throws GateException when the directory doesn't exist.
164 */
165 public boolean importDir(String dirName) throws GateException {
166 File dir = new File(dirName);
167 if(! dir.exists() || ! dir.isDirectory())
168 throw new GateException(dirName + " is not an existing directory");
169
170 List com = new ArrayList();
171 com.add(getCommandName());
172 com.add("import");
173 com.add("-m");
174 com.add("imported");
175 com.add(dir.getName());
176 com.add(getRoot() + "/" + dir.getName());
177 String[] comArray = (String[]) com.toArray(new String[com.size()]);
178
179 // adjust working directory for duration of command
180 File oldWorkingDir = workingDir;
181 workingDir = dir.getParentFile();
182 boolean result = runCommand(comArray);
183 workingDir = oldWorkingDir;
184
185 return result;
186 } // importDir()
187
188 /**
189 * Use the repository's status command to figure out if the file has been
190 * locally modified.
191 * @param fileName the file or directory to work on (should be relative
192 * to the repository's working directory, and use "/" as a path separator).
193 * @return boolean giving status indication.
194 */
195 public boolean isModified(String fileName) {
196 String statusString = status(fileName);
197 if(DEBUG) Out.prln(">>" + statusString + "<<");
198 if(statusString != null && statusString.startsWith("M"))
199 return true;
200 else
201 return false;
202 } // isModified()
203
204 /**
205 * Use the repository's status command to figure out if the file is
206 * out-of-date.
207 * @param fileName the file or directory to work on (should be relative
208 * to the repository's working directory, and use "/" as a path separator).
209 * @return boolean giving status indication.
210 */
211 public boolean isOutOfDate(String fileName) {
212 String statusString = status(fileName);
213 if(statusString == null) return false;
214 char updateFlag = statusString.charAt(7);
215 if(DEBUG) Out.prln(">>" + updateFlag + "<<");
216 if(DEBUG) Out.prln(">>" + statusString + "<<");
217 if(updateFlag == '*')
218 return true;
219 else
220 return false;
221 } // isOutOfDate()
222
223 /**
224 * Use the repository's status command to figure out if the file is
225 * unknown.
226 * @param fileName the file or directory to work on (should be relative
227 * to the repository's working directory, and use "/" as a path separator).
228 * @return boolean giving status indication.
229 */
230 public boolean isUnknown(String fileName) {
231 String statusString = status(fileName);
232 if(DEBUG) Out.prln(">>" + statusString + "<<");
233 if(DEBUG) Out.prln(getCommandOutput());
234 if(statusString == null && getCommandStderr().indexOf("not a working copy") >= 0)
235 //if(statusString == null && getCommandStderr().contains("not a working copy"))
236 return true;
237 else
238 return false;
239 } // isUnknown()
240
241 /**
242 * Check for the existence of a module (i.e. top-level directory).
243 * @param moduleName directory to look for.
244 * @return boolean giving status indication.
245 */
246 public boolean exists(String moduleName) {
247 List com = new ArrayList();
248 com.add(getCommandName());
249 com.add("ls");
250 com.add(getRoot() + "/" + moduleName);
251 String[] comArray = (String[]) com.toArray(new String[com.size()]);
252 boolean result = runCommand(comArray);
253 return result;
254 } // exists()
255
256 } // SvnRepository
|