%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
nl.toolforge.karma.core.boot.WorkingContext |
|
|
1 | /* |
|
2 | Karma core - Core of the Karma application |
|
3 | Copyright (C) 2004 Toolforge <www.toolforge.nl> |
|
4 | ||
5 | This library is free software; you can redistribute it and/or |
|
6 | modify it under the terms of the GNU Lesser General Public |
|
7 | License as published by the Free Software Foundation; either |
|
8 | version 2.1 of the License, or (at your option) any later version. |
|
9 | ||
10 | This library 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. See the GNU |
|
13 | Lesser General Public License for more details. |
|
14 | ||
15 | You should have received a copy of the GNU Lesser General Public |
|
16 | License along with this library; if not, write to the Free Software |
|
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
18 | */ |
|
19 | package nl.toolforge.karma.core.boot; |
|
20 | ||
21 | import nl.toolforge.karma.core.ErrorCode; |
|
22 | import nl.toolforge.karma.core.KarmaRuntimeException; |
|
23 | import nl.toolforge.karma.core.location.LocationException; |
|
24 | import nl.toolforge.karma.core.location.LocationLoader; |
|
25 | import nl.toolforge.karma.core.manifest.ManifestCollector; |
|
26 | import nl.toolforge.karma.core.manifest.ManifestLoader; |
|
27 | import org.apache.commons.io.FileUtils; |
|
28 | import org.apache.commons.logging.Log; |
|
29 | import org.apache.commons.logging.LogFactory; |
|
30 | import org.apache.log4j.FileAppender; |
|
31 | import org.apache.log4j.Level; |
|
32 | import org.apache.log4j.Logger; |
|
33 | import org.apache.log4j.PatternLayout; |
|
34 | ||
35 | import java.io.File; |
|
36 | import java.io.FileInputStream; |
|
37 | import java.io.FileNotFoundException; |
|
38 | import java.io.IOException; |
|
39 | import java.util.Properties; |
|
40 | ||
41 | /** |
|
42 | * <p>A <code>WorkingContext</code> is used by Karma to determine the environment in which the user wants to use Karma. A |
|
43 | * working context is represented on your local harddisk by a directory in which a developers' project work will be |
|
44 | * stored. The <code>WorkingContext</code> class is the bridge from Karma domain objects (<code>Manifest</code> and |
|
45 | * <code>Module</code> to name the most important ones) to a developer's harddisk. |
|
46 | * |
|
47 | * <p>A WorkingContext should be configured before it can be constructed. The |
|
48 | 130 | * {@link #configure(WorkingContextConfiguration)}-method should be called to configure a WorkingContext. |
49 | * |
|
50 | 98 | * @author D.A. Smedes |
51 | 26 | * @version $Id: WorkingContext.java,v 1.24 2004/11/16 22:18:28 hippe Exp $ |
52 | */ |
|
53 | public final class WorkingContext { |
|
54 | ||
55 | 98 | public final static ErrorCode CANNOT_REMOVE_ACTIVE_WORKING_CONTEXT = new ErrorCode("WCO-00001"); |
56 | ||
57 | public final static String WORKING_CONTEXT_PREFERENCE = "karma.working-context"; |
|
58 | ||
59 | private final static String DEFAULT_CONVERSION_PATTERN = "%d{HH:mm:ss} [%5p] - %m%n"; |
|
60 | 260 | |
61 | static { |
|
62 | 196 | |
63 | 52 | // Configure the logging system. |
64 | // |
|
65 | try { |
|
66 | ||
67 | 196 | if (WorkingContext.class.getClassLoader().getResource("log4j.xml") != null) { |
68 | 130 | |
69 | 0 | Logger.getLogger(WorkingContext.class).info("'Log4j.xml' used to for logging configuration."); |
70 | 228 | |
71 | 156 | } else { |
72 | 98 | |
73 | 124 | // Initialize default logging. |
74 | 26 | |
75 | 228 | Logger root = Logger.getRootLogger(); |
76 | ||
77 | 326 | String karmaHome = System.getProperty("karma.home", System.getProperty("user.home")); |
78 | 110 | |
79 | 228 | // Create the log directory |
80 | 156 | // |
81 | 242 | new File(karmaHome, "logs").mkdirs(); |
82 | 166 | |
83 | 138 | File defaultLogFile = new File(karmaHome, "logs/karma-default.log"); |
84 | 152 | |
85 | 144 | PatternLayout patternLayout = new PatternLayout(DEFAULT_CONVERSION_PATTERN); |
86 | 84 | //the log file will be truncated everytime it is opened. |
87 | 200 | FileAppender fileAppender = new FileAppender(patternLayout, defaultLogFile.getPath(), false); |
88 | 166 | fileAppender.setName("Default Karma logging appender."); |
89 | 270 | |
90 | 198 | // The default Appender for a Logger. We don't want it. |
91 | 186 | // |
92 | 138 | root.removeAppender(root.getAppender("console")); |
93 | 338 | |
94 | 82 | root.addAppender(fileAppender); |
95 | 140 | |
96 | 82 | String logLevel = null; |
97 | 228 | logLevel = (System.getProperty("loglevel") == null ? "DEBUG" : System.getProperty("loglevel")); // Pass 1 |
98 | 228 | logLevel = (logLevel.toUpperCase().matches("ALL|DEBUG|ERROR|FATAL|INFO|OFF|WARN") ? logLevel : "DEBUG"); // Pass 2 |
99 | 270 | |
100 | 138 | root.setLevel(Level.toLevel(logLevel)); |
101 | 338 | |
102 | 68 | // By default, disable commons.digester messages. |
103 | 56 | // |
104 | 82 | Logger dig = Logger.getLogger("org.apache.commons.digester"); |
105 | 98 | dig.isAttached(fileAppender); |
106 | 98 | dig.setLevel(Level.OFF); |
107 | 84 | |
108 | 144 | Logger.getLogger(WorkingContext.class).info( |
109 | 84 | "Default logging configuration enabled; override by placing 'log4j.xml' and 'log4j.dtd' on your classpath."); |
110 | 56 | } |
111 | 68 | |
112 | 0 | } catch (Exception e) { |
113 | 56 | e.printStackTrace(); |
114 | 42 | throw new KarmaRuntimeException("*** PANIC *** Log4j system could not be initialized."); |
115 | 144 | } |
116 | 84 | } |
117 | ||
118 | 14 | public static final String CONFIGURATION_BASE_DIRECTORY = System.getProperty("user.home") + File.separator + ".karma"; |
119 | 84 | |
120 | ||
121 | /** |
|
122 | * Property indicating the base directory for development projects. All manifests will be checked out under this |
|
123 | * directory, and the manifest store and location store are checked out at this location as well. |
|
124 | */ |
|
125 | public static final String PROJECT_BASE_DIRECTORY_PROPERTY = "project.basedir"; |
|
126 | ||
127 | /** |
|
128 | * Property indicating the root of a repository directory `Maven style`. For those who don't know Maven, check out |
|
129 | * the <a href="http://maven.apache.org">Maven</a> website. This directory does not have to be the default Maven |
|
130 | * repository directory. It can be any directory on a users' harddisk, as long as binary dependencies can be resolved |
|
131 | * `Maven style`, because that is what Karma does as well. |
|
132 | */ |
|
133 | public static final String PROJECT_LOCAL_REPOSITORY_PROPERTY = "project.local.repository"; |
|
134 | ||
135 | public static final String MANIFEST_STORE_MODULE = "manifest-store.module"; |
|
136 | public static final String LOCATION_STORE_MODULE = "location-store.module"; |
|
137 | ||
138 | /** |
|
139 | * The property that identifies the local directory where jar dependencies can be found. Dependencies are |
|
140 | * resolved Maven style, but to support environments where Maven is not available, the directory is configurable. |
|
141 | * The default Maven repository is used when this property is not set in <code>karma.properties</code>. |
|
142 | */ |
|
143 | ||
144 | 26 | /** The default working context. */ |
145 | public static final String DEFAULT = "default"; |
|
146 | 76 | |
147 | 200 | private static File localRepository = null; |
148 | 332 | |
149 | 276 | private String workingContext = null; |
150 | 846 | |
151 | 200 | private ManifestCollector manifestCollector = null; |
152 | 636 | private ManifestLoader manifestLoader = null; |
153 | 636 | private LocationLoader locationLoader = null; |
154 | 360 | |
155 | 116 | private WorkingContextConfiguration configuration = null; |
156 | 240 | |
157 | 40 | private static final Log logger = LogFactory.getLog(WorkingContext.class); |
158 | 654 | |
159 | 544 | private static File configurationBaseDir = null; |
160 | 550 | |
161 | 42 | /** |
162 | 410 | * Constructs a <code>WorkingContext</code> in the default configuration base directory. The |
163 | * {@link #configure(WorkingContextConfiguration)}-method should be called to configure this working context. |
|
164 | * |
|
165 | * @param workingContext A working context name. If <code>workingContext</code> doesn't match the <code>\w+</code> |
|
166 | * pattern, {@link DEFAULT} is assumed. |
|
167 | 2 | */ |
168 | 2 | public WorkingContext(String workingContext) { |
169 | 2 | this(workingContext, new File(CONFIGURATION_BASE_DIRECTORY)); |
170 | 22 | } |
171 | 26 | |
172 | 6 | /** |
173 | 10 | * Constructs a <code>WorkingContext</code> with <code>configBaseDir</code> as the configuration base directory. When |
174 | 10 | * <code>configBaseDir</code> does not exist, it will be created. The {@link #configure(WorkingContextConfiguration)}- |
175 | * method should be called to configure this working context. |
|
176 | * |
|
177 | * @param workingContext A working context name. If <code>workingContext</code> doesn't match the <code>\w+</code> |
|
178 | * pattern, {@link DEFAULT} is assumed. |
|
179 | 76 | * @param configBaseDir The configuration base directory. If the directory does not exist, it will be created. |
180 | */ |
|
181 | 116 | public WorkingContext(String workingContext, File configBaseDir) { |
182 | 404 | |
183 | 160 | if (!workingContext.matches("\\w[\\w\\-]*")) { |
184 | 888 | workingContext = DEFAULT; |
185 | 140 | } |
186 | 532 | this.workingContext = workingContext; |
187 | 420 | |
188 | 160 | if (configBaseDir == null) { |
189 | 886 | throw new IllegalArgumentException("Configuration base directory cannot be null."); |
190 | 196 | } |
191 | 526 | configurationBaseDir = configBaseDir; |
192 | 440 | configurationBaseDir.mkdirs(); |
193 | 560 | } |
194 | 994 | |
195 | 530 | /** |
196 | * Returns a <code>File</code> reference to the default base directory for Karma configuration files. When the |
|
197 | * directory does not exist, it is created. |
|
198 | 64 | * |
199 | * @return A <code>File</code> reference to the default base directory for Karma configuration files. |
|
200 | 64 | */ |
201 | 64 | public static File getConfigurationBaseDir() { |
202 | 2 | |
203 | 70 | if (configurationBaseDir == null) { |
204 | 762 | throw new KarmaRuntimeException( |
205 | 210 | "For all practical purposes, the configuration base directory has to " + |
206 | 64 | "be initialized. The static call you made should be preceded once by calling the " + |
207 | "WorkingContext constructor (will be replaced by a better solution in later releases)."); |
|
208 | } |
|
209 | 70 | return configurationBaseDir; |
210 | 700 | } |
211 | 210 | |
212 | public void configure(WorkingContextConfiguration configuration) { |
|
213 | 32 | if (configuration == null) { |
214 | 1020 | throw new IllegalArgumentException("Configuration cannot be null for a working context."); |
215 | 796 | } |
216 | ||
217 | 732 | this.configuration = configuration; |
218 | 1020 | |
219 | 128 | String p = configuration.getProperty(PROJECT_LOCAL_REPOSITORY_PROPERTY); |
220 | 352 | if (p == null || "".equals(p)) { |
221 | 1117 | localRepository = new File(System.getProperty("user.home"), ".maven/repository"); |
222 | 106 | } else { |
223 | 34 | localRepository = new File(p); |
224 | 310 | } |
225 | 125 | } |
226 | 1020 | |
227 | 796 | /** |
228 | 0 | * Returns the name of this working context. |
229 | * |
|
230 | * @return The name of this working context. |
|
231 | 700 | */ |
232 | public String getName() { |
|
233 | 103 | return workingContext; |
234 | 210 | } |
235 | ||
236 | /** |
|
237 | * Get the configuration for this working context or <code>null</code> it this working context had not been |
|
238 | * configured. |
|
239 | * |
|
240 | 1120 | * @return The configuration for this working context. |
241 | 0 | */ |
242 | public WorkingContextConfiguration getConfiguration() { |
|
243 | 349 | return configuration; |
244 | 990 | } |
245 | ||
246 | /** |
|
247 | * Get the properties of this working context. The properties are |
|
248 | 6250 | * stored in the karma.properties, which are located in the project base dir. |
249 | * |
|
250 | * @return A Properties object containing the properties of this working |
|
251 | * context or an empty Properties object when something went wrong. |
|
252 | 6250 | */ |
253 | 140 | public Properties getProperties() { |
254 | 105 | Properties properties = new Properties(); |
255 | 0 | try { |
256 | 0 | properties.load(new FileInputStream(class="keyword">new File(getProjectBaseDirectory(), "karma.properties"))); |
257 | 0 | } catch (FileNotFoundException fnfe) { |
258 | 0 | logger.info("karma.properties not found for working context '"+getName()+"'."); |
259 | 0 | } catch (IOException ioe) { |
260 | 0 | logger.error("karma.properties could not be loaded for working context '"+getName()+"'", ioe); |
261 | 0 | } |
262 | 0 | return properties; |
263 | 660 | } |
264 | 495 | |
265 | /** |
|
266 | * Removes a working contexts' configuration directory. |
|
267 | */ |
|
268 | public synchronized void remove() throws IOException { |
|
269 | 0 | FileUtils.deleteDirectory(getWorkingContextConfigurationBaseDir()); |
270 | 0 | } |
271 | ||
272 | ||
273 | /** |
|
274 | 6 | * Returns a <code>File</code> reference to the configuration directory for the current working context. When the |
275 | 6 | * directory does not exist, it is created. This method will return the directory <code>File</code> reference to |
276 | * <code>$HOME/.karma/working-contexts/<working-context-name></code>. |
|
277 | 6 | * |
278 | 6 | * @return a <code>File</code> reference to the configuration directory for the current working context. |
279 | 4 | */ |
280 | public File getWorkingContextConfigurationBaseDir() { |
|
281 | 2966 | |
282 | // Create the base configuration directory the base directory where working contexts are stored. |
|
283 | // |
|
284 | 3059 | File workingContextsDir = new File(configurationBaseDir, "working-contexts"); |
285 | 693 | workingContextsDir.mkdir(); |
286 | 594 | |
287 | 99 | File file = new File(workingContextsDir, workingContext); |
288 | 693 | if (!file.exists()) { |
289 | 628 | file.mkdir(); |
290 | 204 | } |
291 | 99 | return file; |
292 | 778 | } |
293 | ||
294 | 580 | /** |
295 | 693 | * Returns a <code>File</code> reference to the project base directory, which can be configured by the |
296 | 297 | * <code>projects.basedir</code> property in the <code>working-context.xml</code> file. |
297 | 396 | * |
298 | 1967 | * @return a <code>File</code> reference to the project base directory. |
299 | 1707 | */ |
300 | 102 | public File getProjectBaseDirectory() { |
301 | 1486 | |
302 | 1663 | String projectBaseDirProperty = getConfiguration().getProperty(PROJECT_BASE_DIRECTORY_PROPERTY); |
303 | 912 | |
304 | 92 | if (projectBaseDirProperty == null) { |
305 | 1642 | throw new KarmaRuntimeException("Property `project.basedir` is not configured for working context `" + this + "`."); |
306 | } |
|
307 | ||
308 | 92 | File projectBaseDir = new File(projectBaseDirProperty); |
309 | 644 | if (!projectBaseDir.exists()) { |
310 | 552 | projectBaseDir.mkdir(); |
311 | } |
|
312 | 460 | return projectBaseDir; |
313 | 978 | } |
314 | 518 | |
315 | 340 | /** |
316 | 3090 | * Returns a <code>File</code> reference to the administration directory for the working context. In the |
317 | * administration directory, the manifest store and the location store are located for the current working context. |
|
318 | 3608 | * |
319 | 644 | * @return A reference to the administration directory for the current working context. |
320 | 276 | */ |
321 | public File getAdminDir() { |
|
322 | 3458 | |
323 | 3441 | File m = new File(getProjectBaseDirectory(), ".admin"); |
324 | 525 | if (!m.exists()) { |
325 | 482 | m.mkdir(); |
326 | 3282 | } |
327 | ||
328 | 75 | return m; |
329 | 450 | } |
330 | ||
331 | /** |
|
332 | 0 | * Returns a <code>File</code> reference to the manifest store directory for the working context. When the directory |
333 | 300 | * does not exist, it will be created. In this directory, the manifest store will be checked out. |
334 | 525 | * |
335 | 353 | * @return A reference to the manifest store directory. |
336 | 96 | */ |
337 | public File getManifestStoreBasedir() { |
|
338 | 300 | |
339 | 256 | File l = new File(getAdminDir(), "manifest-store"); |
340 | 217 | if (!l.exists()) { |
341 | 217 | l.mkdirs(); |
342 | 186 | } |
343 | ||
344 | 31 | return l; |
345 | 186 | } |
346 | ||
347 | /** |
|
348 | * Returns a <code>File</code> reference to the location store directory for the working context. When the directory |
|
349 | * does not exist, it will be created. In this directory, the location store will be checked out. |
|
350 | * |
|
351 | * @return A reference to the location store directory. |
|
352 | */ |
|
353 | public File getLocationStoreBasedir() { |
|
354 | 0 | |
355 | 43 | File l = new File(getAdminDir(), "location-store"); |
356 | 301 | if (!l.exists()) { |
357 | 289 | l.mkdirs(); |
358 | 186 | } |
359 | ||
360 | 43 | return l; |
361 | 258 | } |
362 | ||
363 | 0 | /** |
364 | * See {@link PROJECT_LOCAL_REPOSITORY_PROPERTY}. When the property is not set, the default repository is |
|
365 | * assumed to be in {@link #getConfigurationBaseDir()}/<code>.repository</code>. |
|
366 | * |
|
367 | * @return See method description. |
|
368 | * |
|
369 | * @see PROJECT_LOCAL_REPOSITORY_PROPERTY |
|
370 | */ |
|
371 | public static File getLocalRepository() { |
|
372 | 0 | return localRepository; |
373 | 2820 | } |
374 | 2820 | |
375 | 412 | public static File getKarmaHome() { |
376 | 62 | |
377 | 63 | if (System.getProperty("karma.home") == null) { |
378 | 2826 | throw new KarmaRuntimeException("KARMA_HOME (karma.home) environment variable has not been set."); |
379 | } |
|
380 | 62 | |
381 | 1 | return new File(System.getProperty("karma.home")); |
382 | 6 | } |
383 | ||
384 | /** |
|
385 | * <p>Determines the last used manifest for this working context. This fact is maintained in the <code>.java</code> file |
|
386 | * on a users' harddisk, as per the specification for <code>java.template.prefs</code>, included in the JDK since |
|
387 | * <code>1.4</code>. |
|
388 | * |
|
389 | * <p>A <code>String</code> made up of the working context name and <code>karma.manifest.last</code>. |
|
390 | */ |
|
391 | 86 | public String getContextManifestPreference() { |
392 | 86 | return getName() + "." + "karma.manifest.last"; |
393 | 62 | } |
394 | ||
395 | 124 | /** |
396 | 303 | * Returns a reference to the <code>LocationLoader</code> for the working context. |
397 | 217 | * @return A location loader. |
398 | 93 | */ |
399 | public LocationLoader getLocationLoader() throws LocationException { |
|
400 | 130 | if (locationLoader == null) { |
401 | 131 | locationLoader = new LocationLoader(this); |
402 | 14 | locationLoader.load(); |
403 | 12 | } |
404 | 6 | return locationLoader; |
405 | 36 | } |
406 | ||
407 | /** |
|
408 | * Returns a reference to the <code>ManifestCollector</code> for the working context. |
|
409 | * @return A manifest loader. |
|
410 | */ |
|
411 | 172 | public ManifestCollector getManifestCollector() { |
412 | 301 | if (manclass="keyword">ifestCollector == null) { |
413 | 255 | manifestCollector = new ManifestCollector(this); |
414 | 93 | } |
415 | 0 | return manifestCollector; |
416 | 172 | } |
417 | 131 | |
418 | /** |
|
419 | * Returns a reference to the <code>ManifestLoader</code> for the working context. |
|
420 | * @return A manifest loader. |
|
421 | */ |
|
422 | public ManifestLoader getManifestLoader() { |
|
423 | 0 | if (manclass="keyword">ifestLoader == null) { |
424 | 0 | manifestLoader = new ManifestLoader(this); |
425 | } |
|
426 | 0 | return manifestLoader; |
427 | } |
|
428 | ||
429 | /** |
|
430 | * Returns the working contexts' name. |
|
431 | * |
|
432 | 1920 | * @return The working contexts' name. |
433 | 1924 | */ |
434 | 343 | public String toString() { |
435 | 0 | return getName(); |
436 | 12 | } |
437 | 1928 | |
438 | 7 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |