1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
|
17 |
|
|
18 |
|
|
19 |
|
package nl.toolforge.karma.core.manifest; |
20 |
|
|
21 |
|
import net.sf.sillyexceptions.OutOfTheBlueException; |
22 |
|
import nl.toolforge.core.util.file.MyFileUtils; |
23 |
|
import nl.toolforge.karma.core.KarmaRuntimeException; |
24 |
|
import nl.toolforge.karma.core.Version; |
25 |
|
import nl.toolforge.karma.core.history.ModuleHistory; |
26 |
|
import nl.toolforge.karma.core.history.ModuleHistoryEvent; |
27 |
|
import nl.toolforge.karma.core.history.ModuleHistoryException; |
28 |
|
import nl.toolforge.karma.core.history.ModuleHistoryFactory; |
29 |
|
import nl.toolforge.karma.core.location.Location; |
30 |
|
import nl.toolforge.karma.core.manifest.util.ModuleLayoutTemplate; |
31 |
|
import nl.toolforge.karma.core.module.ModuleDescriptor; |
32 |
|
import nl.toolforge.karma.core.scm.digester.ModuleDependencyCreationFactory; |
33 |
|
import nl.toolforge.karma.core.vc.AuthenticationException; |
34 |
|
import nl.toolforge.karma.core.vc.Authenticator; |
35 |
|
import nl.toolforge.karma.core.vc.Authenticators; |
36 |
|
import nl.toolforge.karma.core.vc.DevelopmentLine; |
37 |
|
import nl.toolforge.karma.core.vc.PatchLine; |
38 |
|
import nl.toolforge.karma.core.vc.RunnerFactory; |
39 |
|
import nl.toolforge.karma.core.vc.VersionControlException; |
40 |
|
import nl.toolforge.karma.core.vc.cvsimpl.CVSRunner; |
41 |
|
import org.apache.commons.digester.Digester; |
42 |
|
import org.apache.commons.io.FileUtils; |
43 |
|
import org.apache.commons.logging.Log; |
44 |
|
import org.apache.commons.logging.LogFactory; |
45 |
|
import org.xml.sax.SAXException; |
46 |
|
|
47 |
|
import java.io.File; |
48 |
|
import java.io.IOException; |
49 |
|
import java.util.Date; |
50 |
|
import java.util.HashSet; |
51 |
|
import java.util.Set; |
52 |
|
import java.util.regex.PatternSyntaxException; |
53 |
|
|
54 |
|
|
55 |
|
|
56 |
|
|
57 |
|
|
58 |
|
|
59 |
|
|
60 |
|
public abstract class BaseModule implements Module { |
61 |
|
|
62 |
184 |
protected static Log logger = LogFactory.getLog(BaseModule.class); |
63 |
75 |
|
64 |
798 |
private Location location = null; |
65 |
914 |
private String name = null; |
66 |
350 |
|
67 |
876 |
private File baseDir = null; |
68 |
914 |
private File checkoutDir = null; |
69 |
350 |
|
70 |
876 |
private Version version = null; |
71 |
914 |
private boolean patchLine = false; |
72 |
1070 |
private boolean developmentLine = false; |
73 |
350 |
|
74 |
156 |
public BaseModule(String name, Location location, Version version) { |
75 |
224 |
this(name, location); |
76 |
356 |
this.version = version; |
77 |
512 |
} |
78 |
288 |
|
79 |
876 |
public BaseModule(String name, Location location) { |
80 |
194 |
|
81 |
876 |
if (!name.matches(ModuleDigester.NAME_PATTERN_STRING)) { |
82 |
194 |
throw new PatternSyntaxException( |
83 |
156 |
"Pattern mismatch for 'name'. Should match " + ModuleDigester.NAME_PATTERN_STRING, name, -1); |
84 |
|
} |
85 |
720 |
if (location == null) { |
86 |
194 |
throw new IllegalArgumentException("Location cannot be null."); |
87 |
156 |
} |
88 |
|
|
89 |
720 |
this.name = name; |
90 |
914 |
this.location = location; |
91 |
1070 |
} |
92 |
350 |
|
93 |
156 |
|
94 |
|
|
95 |
|
|
96 |
|
|
97 |
|
|
98 |
|
public final String getName() { |
99 |
1000 |
return name; |
100 |
649 |
} |
101 |
786 |
|
102 |
|
|
103 |
|
|
104 |
|
|
105 |
|
|
106 |
|
|
107 |
|
public final Location getLocation() { |
108 |
416 |
return location; |
109 |
400 |
} |
110 |
492 |
|
111 |
|
public boolean equals(Object obj) { |
112 |
|
|
113 |
0 |
if (obj instanceof BaseModule) { |
114 |
0 |
if (((BaseModule) obj).getName().equals(getName()) && |
115 |
|
((BaseModule) obj).getLocation().equals(getLocation())) { |
116 |
0 |
return true; |
117 |
|
} |
118 |
|
} |
119 |
0 |
return false; |
120 |
|
} |
121 |
|
|
122 |
|
public int hashCode() { |
123 |
0 |
return getName().hashCode() + getLocation().hashCode(); |
124 |
20 |
} |
125 |
30 |
|
126 |
|
|
127 |
|
|
128 |
|
|
129 |
|
|
130 |
|
|
131 |
|
|
132 |
|
public final boolean hasDevelopmentLine() { |
133 |
0 |
return false; |
134 |
|
} |
135 |
|
|
136 |
|
public final void markDevelopmentLine(boolean mark) { |
137 |
0 |
developmentLine = mark; |
138 |
20 |
} |
139 |
50 |
|
140 |
30 |
public final DevelopmentLine getPatchLine() { |
141 |
16 |
return new PatchLine(getVersion()); |
142 |
15 |
} |
143 |
18 |
|
144 |
|
public final void markPatchLine(boolean mark) { |
145 |
16 |
patchLine = true; |
146 |
26 |
} |
147 |
22 |
|
148 |
12 |
public final Version getVersion() { |
149 |
48 |
return version; |
150 |
75 |
} |
151 |
102 |
|
152 |
|
|
153 |
|
|
154 |
|
|
155 |
|
|
156 |
|
|
157 |
|
|
158 |
|
public final String getVersionAsString() { |
159 |
16 |
return (version == null ? "N/A" : version.getVersionNumber()); |
160 |
10 |
} |
161 |
12 |
|
162 |
|
public final boolean hasVersion() { |
163 |
88 |
return version != null; |
164 |
35 |
} |
165 |
36 |
|
166 |
|
|
167 |
|
|
168 |
|
|
169 |
|
|
170 |
|
|
171 |
|
|
172 |
|
|
173 |
|
public final boolean hasPatchLine() { |
174 |
8 |
return patchLine; |
175 |
5 |
} |
176 |
6 |
|
177 |
|
|
178 |
|
|
179 |
|
|
180 |
|
|
181 |
|
|
182 |
|
|
183 |
|
public final void setBaseDir(File baseDir) { |
184 |
|
|
185 |
704 |
if (baseDir == null) { |
186 |
192 |
throw new IllegalArgumentException("If you use it, initialize it with a valid 'File' instance ..."); |
187 |
156 |
} |
188 |
704 |
this.baseDir = baseDir; |
189 |
896 |
} |
190 |
348 |
|
191 |
156 |
public final File getBaseDir() { |
192 |
|
|
193 |
1696 |
if (baseDir == null) { |
194 |
498 |
throw new KarmaRuntimeException("Basedir not set."); |
195 |
498 |
} |
196 |
1696 |
return baseDir; |
197 |
498 |
} |
198 |
498 |
|
199 |
|
public abstract ModuleLayoutTemplate getLayoutTemplate(); |
200 |
|
|
201 |
|
|
202 |
96 |
|
203 |
144 |
|
204 |
|
|
205 |
96 |
|
206 |
240 |
|
207 |
144 |
public final void createRemote(Authenticator authenticator, String createComment) throws AuthenticationException, VersionControlException { |
208 |
|
|
209 |
|
|
210 |
|
|
211 |
32 |
File tmpDir = null; |
212 |
|
try { |
213 |
32 |
tmpDir = MyFileUtils.createTempDirectory(); |
214 |
0 |
} catch (IOException e) { |
215 |
96 |
throw new KarmaRuntimeException("Could not create temporary directory."); |
216 |
176 |
} |
217 |
|
|
218 |
128 |
File moduleDir = new File(tmpDir, getName()); |
219 |
176 |
moduleDir.mkdir(); |
220 |
|
|
221 |
|
|
222 |
|
|
223 |
|
try { |
224 |
32 |
getLayoutTemplate().createLayout(moduleDir); |
225 |
0 |
} catch (IOException e) { |
226 |
|
|
227 |
0 |
e.printStackTrace(); |
228 |
32 |
} |
229 |
|
|
230 |
32 |
logger.debug("Created layout for module `" + getName() + "`"); |
231 |
|
|
232 |
|
|
233 |
20 |
|
234 |
56 |
setBaseDir(moduleDir); |
235 |
20 |
|
236 |
56 |
ModuleDescriptor descriptor = new ModuleDescriptor(this); |
237 |
|
try { |
238 |
52 |
descriptor.createFile(moduleDir); |
239 |
24 |
} catch (IOException e) { |
240 |
20 |
|
241 |
44 |
e.printStackTrace(); |
242 |
56 |
} |
243 |
|
|
244 |
|
|
245 |
|
|
246 |
52 |
ModuleHistory history = null; |
247 |
24 |
try { |
248 |
32 |
history = ModuleHistoryFactory.getInstance(getBaseDir()).getModuleHistory(this); |
249 |
0 |
} catch (ModuleHistoryException e) { |
250 |
20 |
throw new OutOfTheBlueException("Module history does not yet exist, so this is impossible."); |
251 |
56 |
} |
252 |
20 |
|
253 |
56 |
ModuleHistoryEvent event = new ModuleHistoryEvent(); |
254 |
32 |
event.setType(ModuleHistoryEvent.CREATE_MODULE_EVENT); |
255 |
32 |
event.setVersion(Version.INITIAL_VERSION); |
256 |
48 |
event.setDatetime(new Date()); |
257 |
44 |
|
258 |
24 |
|
259 |
20 |
|
260 |
56 |
Authenticator a = Authenticators.getAuthenticator(authenticator); |
261 |
20 |
|
262 |
56 |
event.setAuthor(a.getUsername()); |
263 |
32 |
event.setComment(createComment); |
264 |
32 |
history.addEvent(event); |
265 |
20 |
try { |
266 |
56 |
history.save(); |
267 |
0 |
} catch (ModuleHistoryException mhe) { |
268 |
0 |
logger.error("Troubles when saving the module history.", mhe); |
269 |
52 |
} |
270 |
24 |
|
271 |
52 |
CVSRunner runner = (CVSRunner) RunnerFactory.getRunner(getLocation()); |
272 |
56 |
runner.addModule(this, createComment); |
273 |
|
|
274 |
20 |
try { |
275 |
56 |
FileUtils.deleteDirectory(tmpDir); |
276 |
20 |
} catch (IOException e) { |
277 |
44 |
logger.warn("Could not remove temporary directory. It is probably still locked by the OS."); |
278 |
76 |
} |
279 |
76 |
} |
280 |
24 |
|
281 |
|
|
282 |
|
|
283 |
20 |
|
284 |
24 |
|
285 |
20 |
|
286 |
44 |
|
287 |
44 |
|
288 |
36 |
|
289 |
32 |
public final Type getType() throws ModuleTypeException { |
290 |
12 |
|
291 |
36 |
try { |
292 |
64 |
getBaseDir(); |
293 |
0 |
} catch (KarmaRuntimeException k) { |
294 |
20 |
return Module.UNKNOWN; |
295 |
64 |
} |
296 |
|
|
297 |
44 |
if (!new File(getBaseDir(), Module.MODULE_DESCRIPTOR).exists()) { |
298 |
44 |
throw new ModuleTypeException(ModuleTypeException.MISSING_MODULE_DESCRIPTOR); |
299 |
24 |
} |
300 |
|
|
301 |
40 |
Digester digester = new Digester(); |
302 |
8 |
|
303 |
32 |
digester.addObjectCreate("module-descriptor", Module.Type.class); |
304 |
32 |
digester.addCallMethod("module-descriptor/type", "setType", 0); |
305 |
|
|
306 |
|
try { |
307 |
32 |
return (Type) digester.parse(new File(getBaseDir(), Module.MODULE_DESCRIPTOR).getPath()); |
308 |
0 |
} catch (IOException e) { |
309 |
0 |
throw new ModuleTypeException(ModuleTypeException.INVALID_MODULE_DESCRIPTOR); |
310 |
0 |
} catch (SAXException e) { |
311 |
12 |
throw new ModuleTypeException(ModuleTypeException.INVALID_MODULE_DESCRIPTOR); |
312 |
24 |
} |
313 |
|
} |
314 |
12 |
|
315 |
32 |
|
316 |
12 |
|
317 |
24 |
|
318 |
8 |
|
319 |
|
|
320 |
20 |
|
321 |
24 |
|
322 |
12 |
public final Set getDependencies() { |
323 |
36 |
|
324 |
32 |
Set dependencies = new HashSet(); |
325 |
|
|
326 |
20 |
|
327 |
32 |
|
328 |
0 |
Digester digester = new Digester(); |
329 |
|
|
330 |
8 |
digester.addObjectCreate("*/dependencies", HashSet.class); |
331 |
0 |
digester.addFactoryCreate("*/dependency", ModuleDependencyCreationFactory.class); |
332 |
0 |
digester.addSetNext("*/dependency", "add"); |
333 |
|
|
334 |
|
try { |
335 |
|
|
336 |
0 |
dependencies = (Set) digester.parse(new File(getBaseDir(), "dependencies.xml")); |
337 |
|
|
338 |
0 |
} catch (IOException e) { |
339 |
0 |
return new HashSet(); |
340 |
0 |
} catch (SAXException e) { |
341 |
0 |
throw new KarmaRuntimeException(ManifestException.DEPENDENCY_FILE_LOAD_ERROR, class="keyword">new Object[]{getName()}); |
342 |
0 |
} |
343 |
0 |
return dependencies; |
344 |
|
} |
345 |
|
|
346 |
|
|
347 |
|
|
348 |
|
|
349 |
|
|
350 |
|
|
351 |
|
public String toString() { |
352 |
0 |
return getName(); |
353 |
|
} |
354 |
|
|
355 |
|
} |