1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package nl.toolforge.karma.core.vc.cvsimpl;
20
21 import nl.toolforge.karma.core.KarmaRuntimeException;
22 import nl.toolforge.karma.core.Patch;
23 import nl.toolforge.karma.core.Version;
24 import nl.toolforge.karma.core.module.Module;
25 import nl.toolforge.karma.core.vc.DevelopmentLine;
26 import nl.toolforge.karma.core.vc.ModuleStatus;
27 import nl.toolforge.karma.core.vc.PatchLine;
28 import nl.toolforge.karma.core.vc.model.MainLine;
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.netbeans.lib.cvsclient.admin.Entry;
32 import org.netbeans.lib.cvsclient.admin.StandardAdminHandler;
33 import org.netbeans.lib.cvsclient.command.log.LogInformation;
34
35 import java.io.IOException;
36 import java.util.ArrayList;
37 import java.util.Collection;
38 import java.util.Collections;
39 import java.util.Iterator;
40 import java.util.List;
41 import java.util.regex.Matcher;
42 import java.util.regex.Pattern;
43 import java.util.regex.PatternSyntaxException;
44
45 /***
46 * @author D.A. Smedes
47 * @version $Id: CVSModuleStatus.java,v 1.11 2004/11/16 22:31:57 asmedes Exp $
48 */
49 public class CVSModuleStatus implements ModuleStatus {
50
51 private static final Log logger = LogFactory.getLog(Utils.class);
52
53 private boolean existsInRepository = false;
54
55 private List matchingList = null;
56
57 private Module module = null;
58 private LogInformation logInfo = null;
59 private boolean connectionFailure = false;
60 private boolean authenticationFailure = false;
61 private boolean internalError = false;
62
63 /***
64 * Creates a ModuleStatus instance with the LogInformation object that was generated by the <code>cvs log</code>
65 * command.
66 *
67 * @param module The module.
68 * @param logInfo A Netbeans LogInformation object.
69 */
70 public CVSModuleStatus(Module module, LogInformation logInfo) {
71 this.module = module;
72 setLogInformation(logInfo);
73 }
74
75 public CVSModuleStatus(Module module) {
76 this.module = module;
77 }
78
79 public void setLogInformation(Object logInfo) {
80 this.logInfo = (LogInformation) logInfo;
81 matchingList = collectVersions(module);
82 }
83
84 /***
85 * Returns a Version instance representing the next possible version (major or patch) for the module.
86 *
87 * @return
88 */
89 public Version getNextVersion() {
90
91 if (matchingList.size() == 0) {
92
93
94
95
96
97
98
99 if (module.hasPatchLine()) {
100 return module.getVersion().createPatch(Patch.INITIAL_PATCH);
101 }
102
103 return null;
104 }
105
106 Version nextVersion = null;
107
108 try {
109 nextVersion = (Version) ((Version) matchingList.get(matchingList.size() - 1)).clone();
110 } catch (CloneNotSupportedException e) {
111 throw new KarmaRuntimeException(e.getMessage(), e);
112 }
113
114 nextVersion.increase();
115
116 return nextVersion;
117 }
118
119 public Version getNextMajorVersion() {
120 if (matchingList.size() == 0) {
121 return null;
122 }
123
124 Version nextVersion = null;
125
126 try {
127 nextVersion = (Version) ((Version) matchingList.get(matchingList.size() - 1)).clone();
128 } catch (CloneNotSupportedException e) {
129 throw new KarmaRuntimeException(e.getMessage(), e);
130 }
131
132 nextVersion.increaseMajor();
133
134 return nextVersion;
135 }
136
137 /***
138 * The latest promoted version of the module in the version control system for the branch.
139 *
140 * @return
141 */
142 public Version getLastVersion() {
143
144 if (matchingList.size() == 0) {
145
146 if (module.hasPatchLine()) {
147 return module.getVersion();
148 } else {
149 return null;
150 }
151 }
152 return (Version) matchingList.get(matchingList.size() - 1);
153 }
154
155 /***
156 * Gets the local version of the module, which is determined by parsing the <code>CVS/Entries</code> file.
157 *
158 * @return The version of the local checkout or <code>null</code> when the HEAD of the developmentline is local.
159 * @throws CVSException
160 */
161 public Version getLocalVersion() throws CVSException {
162 logger.debug("Retrieving local version for module: "+module.getName());
163 StandardAdminHandler handler = new StandardAdminHandler();
164 Version localVersion = null;
165
166 try {
167 Entry[] entries = handler.getEntriesAsArray(module.getBaseDir());
168
169 Entry moduleDescriptor = null;
170
171 int i = 0;
172 while (i < entries.length) {
173 if (entries[i].getName().equals(Module.MODULE_DESCRIPTOR)) {
174 moduleDescriptor = entries[i];
175 break;
176 }
177 i++;
178 }
179 try {
180
181 if (moduleDescriptor == null || moduleDescriptor.getTag() == null || moduleDescriptor.getTag().matches(DevelopmentLine.DEVELOPMENT_LINE_PATTERN_STRING)) {
182 logger.debug("We're on the head. Return null.");
183
184
185 return null;
186 }
187 if (moduleDescriptor.getTag().startsWith(PatchLine.NAME_PREFIX)) {
188 localVersion = new Patch(moduleDescriptor.getTag().substring(moduleDescriptor.getTag().indexOf("_") + 1));
189 logger.debug("PatchLine. Return "+localVersion);
190 } else {
191 localVersion = new Version(moduleDescriptor.getTag().substring(moduleDescriptor.getTag().indexOf("_") + 1));
192 logger.debug("MainLine. Return "+localVersion);
193 }
194
195 } catch (Exception e) {
196 throw new CVSException(CVSException.LOCAL_MODULE_ERROR, new Object[]{module.getName()});
197 }
198
199 } catch (IOException e) {
200 throw new CVSException(CVSException.LOCAL_MODULE_ERROR, new Object[]{module.getName()});
201 }
202 return localVersion;
203 }
204
205 public void setExistsInRepository(boolean exists) {
206 existsInRepository = exists;
207 }
208
209 public boolean existsInRepository() {
210 return existsInRepository;
211 }
212
213 private List collectVersions(Module module) {
214
215 if (logInfo == null) {
216 return new ArrayList();
217 }
218
219
220
221
222 List matchingList = new ArrayList();
223
224 Collection currentVersions = logInfo.getAllSymbolicNames();
225
226 Pattern pattern = null;
227
228 if (module.hasPatchLine()) {
229
230
231
232 pattern = Pattern.compile(((PatchLine) module.getPatchLine()).getMatchingPattern());
233 } else {
234
235
236 pattern = Pattern.compile(MainLine.NAME_PREFIX.concat("_").concat(Version.VERSION_PATTERN_STRING));
237 }
238
239
240
241 for (Iterator it = currentVersions.iterator(); it.hasNext();) {
242
243 String s = ((LogInformation.SymName) it.next()).getName();
244
245 Matcher matcher = pattern.matcher(s);
246 if (matcher.matches()) {
247
248 try {
249 if (module.hasPatchLine()) {
250 matchingList.add(new Patch(s.substring(s.lastIndexOf("_") + 1)));
251 } else {
252 matchingList.add(new Version(s.substring(s.lastIndexOf("_") + 1)));
253 }
254 } catch (PatternSyntaxException p) {
255
256 }
257 }
258 }
259
260
261
262 Collections.sort(matchingList);
263
264 return matchingList;
265 }
266
267 public boolean connectionFailure() {
268 return connectionFailure;
269 }
270
271 public boolean authenticationFailure() {
272 return authenticationFailure;
273 }
274
275 public boolean internalError() {
276 return internalError;
277 }
278
279 /***
280 * Sets the indication that a connection failure to the remote CVS repository has occurred.
281 */
282 public void setConnnectionFailure() {
283 connectionFailure = true;
284 }
285
286 public void setAuthenticationFailure() {
287 authenticationFailure = true;
288 }
289
290 public void setInternalError() {
291 internalError = true;
292 }
293 }