Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that implements system utility methods 
4
 *  Copyright: 2008 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Michael Daigle
7
 * 
8
 *   '$Author: daigle $'
9
 *     '$Date: 2009-01-02 08:16:16 -0800 (Fri, 02 Jan 2009) $'
10
 * '$Revision: 4725 $'
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 2 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program; if not, write to the Free Software
24
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
 */
26

    
27
package edu.ucsb.nceas.metacat.util;
28

    
29
import java.io.IOException;
30
import java.util.regex.Matcher;
31
import java.util.regex.Pattern;
32
import javax.servlet.ServletContext;
33
import javax.servlet.http.HttpServletRequest;
34

    
35
import org.apache.log4j.Logger;
36

    
37
import edu.ucsb.nceas.metacat.MetaCatVersion;
38
import edu.ucsb.nceas.metacat.service.PropertyService;
39
import edu.ucsb.nceas.utilities.FileUtil;
40
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
41

    
42
public class SystemUtil {
43

    
44
	private static Logger logMetacat = Logger.getLogger(SystemUtil.class);
45
	private static String METACAT_SERVLET = "metacat";
46
	private static int OS_CLASS = 0;
47
	
48
	// Class of OS.  If we need more granularity, we should create a version
49
	// list and access it separately.
50
	public static int WIN_OS = 1;
51
	public static int LINUX_OS = 2;
52
	public static int MAC_OS = 3;
53
	public static int OTHER_OS = 4;
54
	
55
	/**
56
	 * private constructor - all methods are static so there is no no need to
57
	 * instantiate.
58
	 */
59
	private SystemUtil() {}
60

    
61
	/**
62
	 * Get the OS for this system.
63
	 * @return an integer representing the class of OS.  Possibilities are:
64
	 *     WIN_OS = 1;
65
	 *     LINUX_OS = 2;
66
	 *     MAC_OS = 3;
67
	 *     OTHER_OS = 4;
68
	 */
69
	public static int getOsClass() {
70
		if (OS_CLASS > 0) {
71
			return OS_CLASS;
72
		}
73
		
74
		String osName = System.getProperty("os.name");
75
		if (osName.startsWith("Windows")) {
76
			OS_CLASS =  WIN_OS;
77
		} else if (osName.startsWith("Linux")) {
78
			OS_CLASS =  LINUX_OS;
79
		} else if (osName.startsWith("Mac")) {
80
			OS_CLASS =  MAC_OS;
81
		} else if (osName.startsWith("Mac")) {
82
			OS_CLASS =  OTHER_OS;
83
		}
84
		
85
		return OS_CLASS;
86
	}
87
	
88
	/**
89
	 * Attempt to discover the server name. The name is retrieved from the http
90
	 * servlet request. This is used by configuration routines before the port
91
	 * has been populated in metacat.properties. it is possible the port that
92
	 * the user configures might be different than the name we get here. You
93
	 * should use getServerPort() instead of this method whenever possible.
94
	 * 
95
	 * @param request
96
	 *            the http servlet request we will use to find the server name
97
	 * 
98
	 * @return a string holding the server name
99
	 */
100
	public static String discoverServerName(HttpServletRequest request) {
101
		String serverName = request.getServerName();
102

    
103
		return serverName;
104
	}
105

    
106
	/**
107
	 * Attempt to discover the server port. The port is retrieved from the http
108
	 * servlet request. This is used by configuration routines before the port
109
	 * has been populated in metacat.properties. it is possible the port that
110
	 * the user configures might be different than the port we get here. You
111
	 * should use getServerPort() instead of this method whenever possible.
112
	 * 
113
	 * @param request
114
	 *            the http servlet request we will use to find the server port
115
	 * 
116
	 * @return a string holding the server port
117
	 */
118
	public static String discoverServerPort(HttpServletRequest request) {
119
		return Integer.toString(request.getServerPort());
120
	}
121
	
122
	/**
123
	 * Attempt to discover the server ssl port. The ssl port is assumed using
124
	 * the standard port. This is used by configuration routines before the port
125
	 * has been populated in metacat.properties. it is possible the prot that
126
	 * the user configures might be different than the port we get here. You
127
	 * should use getServerSSLPort() instead of this method whenever possible.
128
	 * 
129
	 * @param request
130
	 *            the http servlet request we will use to find the server port
131
	 * 
132
	 * @return a string holding the server ssl port
133
	 */
134
	public static String discoverServerSSLPort(HttpServletRequest request) {
135
		String serverPort = discoverServerPort(request);
136

    
137
		if (serverPort.length() == 4 && serverPort.charAt(0) == '8') {
138
			return "8443";
139
		}
140

    
141
		return "443";
142
	}
143

    
144
	/**
145
	 * Get the server URL which is made up of the server name + : + the http
146
	 * port number. Note that if the port is 80, it is left off.
147
	 * 
148
	 * @return string holding the server URL
149
	 */
150
	public static String getServerURL() throws PropertyNotFoundException {
151
		String ServerURL = "http://" + PropertyService.getProperty("server.name");
152
		String httpPort = PropertyService.getProperty("server.httpPort");
153
		if (!httpPort.equals("80")) {
154
			ServerURL += ":" + httpPort;
155
		}
156

    
157
		return ServerURL;
158
	}
159

    
160
	/**
161
	 * Get the secure server URL which is made up of the server name + : + the
162
	 * https port number. Note that if the port is 443, it is left off.
163
	 * 
164
	 * @return string holding the server URL
165
	 */
166
	public static String getSecureServerURL() throws PropertyNotFoundException {
167
		String ServerURL = "https://" + getSecureServer();
168
		return ServerURL;
169
	}
170
	
171
	/**
172
	 * Get the secure server  which is made up of the server name + : + the
173
	 * https port number. Note that if the port is 443, it is left off.
174
	 * NOTE: does NOT include "https://"
175
	 * @see getSecureServerURL()
176
	 * 
177
	 * @return string holding the secure server
178
	 */
179
	public static String getSecureServer() throws PropertyNotFoundException {
180
		String server = PropertyService.getProperty("server.name");
181
		String httpPort = PropertyService.getProperty("server.httpSSLPort");
182
		if (!httpPort.equals("443")) {
183
			server = server + ":" + httpPort;
184
		}
185

    
186
		return server;
187
	}
188

    
189
	/**
190
	 * Get the CGI URL which is made up of the server URL + file separator + the
191
	 * CGI directory
192
	 * 
193
	 * @return string holding the server URL
194
	 */
195
	public static String getCGI_URL() throws PropertyNotFoundException{
196
		return getContextURL() 
197
				+ PropertyService.getProperty("application.cgiDir");
198
	}
199

    
200
	/**
201
	 * Get the server URL with the context. This is made up of the server URL +
202
	 * file separator + the context
203
	 * 
204
	 * @return string holding the server URL with context
205
	 */
206
	public static String getContextURL() throws PropertyNotFoundException {
207
		return getServerURL() + "/"
208
				+ PropertyService.getProperty("application.context");
209
	}
210

    
211
	/**
212
	 * Get the servlet URL. This is made up of the server URL with context +
213
	 * file separator + the metacat servlet name
214
	 * 
215
	 * @return string holding the servlet URL
216
	 */
217
	public static String getServletURL() throws PropertyNotFoundException {
218
		return getContextURL() + "/" + METACAT_SERVLET;
219
	}
220

    
221
	/**
222
	 * Get the style skins URL. This is made up of the server URL with context +
223
	 * file separator + "style" + file separator + "skins"
224
	 * 
225
	 * @return string holding the style skins URL
226
	 */
227
	public static String getStyleSkinsURL() throws PropertyNotFoundException {
228
		return getContextURL() + "/" + "style" + "/" + "skins";
229
	}
230

    
231
	/**
232
	 * Get the style common URL. This is made up of the server URL with context +
233
	 * file separator + "style" + file separator + "common"
234
	 * 
235
	 * @return string holding the style common URL
236
	 */
237
	public static String getStyleCommonURL() throws PropertyNotFoundException {
238
		return getContextURL() + "/" + "style" + "/" + "common";
239
	}
240
	
241
	/**
242
	 * Get the metacat version by getting the string representation from
243
	 * metacat.properties and instantiating a MetaCatVersion object.
244
	 * The info is set in build.properties and then populated into metacat.properties
245
	 * at build time using Ant token replacement.
246
	 * 
247
	 * @return a MetaCatVersion object holding metacat version information
248
	 */
249
	public static MetaCatVersion getMetacatVersion() throws PropertyNotFoundException {
250
		String metacatVersionString = 
251
			PropertyService.getProperty("application.metacatVersion");
252
		return new MetaCatVersion(metacatVersionString);
253
	}
254
	
255
	/**
256
	 * Gets a string that holds some description about the release. Typically this is 
257
	 * used during release candidates for display purposes and might hold something
258
	 * like "Release Candidate 1".  Normally it is empty for final production release.
259
	 * The info is set in build.properties and then populated into metacat.properties
260
	 * at build time using Ant token replacement.
261
	 * 
262
	 * @return a MetaCatVersion object holding metacat version information
263
	 */
264
	public static String getMetacatReleaseInfo() throws PropertyNotFoundException {
265
		return PropertyService.getProperty("application.metacatReleaseInfo");
266
	}
267

    
268
	/**
269
	 * Get the context directory. This is made up of the deployment directory + file
270
	 * separator + context
271
	 * 
272
	 * @return string holding the context directory
273
	 */
274
	public static String getContextDir() throws PropertyNotFoundException {
275
		return PropertyService.getProperty("application.deployDir") + FileUtil.getFS()
276
				+ PropertyService.getProperty("application.context");
277
	}
278

    
279
	/**
280
	 * Attempt to discover the context for this application. This is a best
281
	 * guess scenario. It is used by configuration routines before the context
282
	 * has been populated in metacat.properties. You should always use
283
	 * getApplicationContext() instead of this method if possible.
284
	 * 
285
	 * @param request
286
	 *            the http servlet request we will use to find the context
287
	 * 
288
	 * @return a string holding the context
289
	 */
290
	public static String discoverApplicationContext(HttpServletRequest request) {
291
		String contextPath = request.getContextPath();
292

    
293
		if (contextPath.charAt(0) == '/') {
294
			contextPath = contextPath.substring(1);
295
		}
296
		logMetacat.debug("contextPath: " + contextPath);
297

    
298
		return contextPath;
299
	}
300
	
301
	/**
302
	 * Attempt to discover the external (to the metacat installation)
303
	 * directory where metacat will hold backup files.   This functionality 
304
	 * is used to populate the configuration utility initially.  The user 
305
	 * can change the directory manually, so you can't rely on this method 
306
	 * to give you the actual directory.  Here are the steps taken to discover
307
	 * the directory:
308
	 * 
309
	 * -- 1) Look for a saved backup location file in the user home dir - Is there a file named 
310
	 *       <user_home>/.metacat/backup-location for the user that started tomcat? if so, does 
311
	 *       it contain a single line which is a readable directory?  This directory was the backup 
312
	 *       directory used during a previous install.  Return that directory.
313
	 * -- 2) Look for an existing hidden (.metacat) directory in a default system directory.  Get 
314
	 *       the default base directory for the OS.  (See application.windowsBackupBaseDir and 
315
	 *       application.linuxBackupBaseDir in metacat.properties.)  If a directory called 
316
	 *       <base_dir>/metacat/.metacat exists, return <base_dir>/metacat.
317
	 * -- 3) Look for an existing hidden (.metacat) directory in the user directory. If a directory 
318
	 *       called <user_dir>/.metacat exists for the user that started tomcat, return <user_dir>.
319
	 * -- 4) Is the <base_dir> writable by the user that started tomcat?  If so, return <base_dir>
320
	 * -- 5) Does the <user_home> exist?  If so, return <user_home>
321
	 * -- 6) Otherwise, return null
322
	 *    
323
	 * @return a string holding the backup directory path
324
	 */
325
	public static String discoverExternalBaseDir() throws PropertyNotFoundException {
326
		String userHomeDir = getUserHomeDir();
327
		String defaultBaseDir = "";
328
		
329
		try {
330
			// Check if there is a file at <user_home>/.metacat/backup-location.  If so, it
331
			// should contain one line that is a file that points to a writable directory. 
332
			// If that is true, use that value as the external dir.
333
			String storedBackupFileLoc = getUserHomeDir() + FileUtil.getFS() + ".metacat"
334
					+ FileUtil.getFS() + "backup-location";
335
			if (FileUtil.getFileStatus(storedBackupFileLoc) >= FileUtil.EXISTS_READABLE) {
336
				String storedBackupDirLoc = FileUtil.readFileToString(storedBackupFileLoc);
337
				if (FileUtil.isDirectory(storedBackupDirLoc)
338
						&& FileUtil.getFileStatus(storedBackupDirLoc) > FileUtil.EXISTS_READABLE) {
339
					return storedBackupDirLoc;
340
				}
341
			}
342
		} catch (IOException ioe) {
343
			logMetacat.warn("Could not read stored backup location: " + ioe.getMessage());
344
		}
345
		
346
		// Set the default location using the os
347
		if (getOsClass() == WIN_OS) {
348
			defaultBaseDir = PropertyService.getProperty("application.windowsBackupBaseDir");
349
		} else {
350
			defaultBaseDir = PropertyService.getProperty("application.linuxBackupBaseDir");
351
		}
352
		
353
		String defaultBackupDir = defaultBaseDir + FileUtil.getFS() + "metacat";
354
		String defaultBackupHiddenDir = defaultBackupDir + FileUtil.getFS() + ".metacat";
355
		String userHomeBackupHiddenDir = userHomeDir + FileUtil.getFS() + ".metacat";
356
		
357
		// If <base_dir>/metacat/.metacat exists, return <base_dir>
358
		if ((FileUtil.getFileStatus(defaultBackupHiddenDir) >= FileUtil.EXISTS_READ_WRITABLE)) {
359
			return defaultBaseDir;
360
		}
361
		
362
		// Otherwise if <user_dir>/.metacat exists, return <user_dir>
363
		if ((FileUtil.getFileStatus(userHomeBackupHiddenDir) >= FileUtil.EXISTS_READ_WRITABLE)) {
364
			return userHomeDir;
365
		}
366
		
367
		// Otherwise if <base_dir>/metacat exists, return <base_dir>
368
		if ((FileUtil.getFileStatus(defaultBaseDir) >= FileUtil.EXISTS_READ_WRITABLE)) {
369
			return defaultBaseDir;
370
		}
371
		
372
		// Otherwise if <user_dir> exists, return <user_dir>
373
		if ((FileUtil.getFileStatus(userHomeDir) >= FileUtil.EXISTS_READ_WRITABLE)) {
374
			return userHomeDir;
375
		}
376
	
377
		// Otherwise, return userHomeDir
378
		return null;
379
	}
380
	
381
	/**
382
	 * Store the location of the backup file location into a file at 
383
	 * <user_home>/.metacat/backup-location
384
	 * 
385
	 * @param externalDir the backup file location.
386
	 */
387
	public static void storeExternalDirLocation(String externalDir) {
388
		if (getUserHomeDir() != null) {
389
			String storedBackupLocDir = getUserHomeDir() + FileUtil.getFS() + ".metacat";
390
			String storedBackupLocFile = storedBackupLocDir + FileUtil.getFS() + "backup-location";
391
			try {
392
				FileUtil.createDirectory(storedBackupLocDir);
393
				FileUtil.writeFile(storedBackupLocFile, externalDir);
394
			} catch (IOException ioe) {
395
				logMetacat.error("I/O error while trying to write stored backup directory: "
396
								+ storedBackupLocFile + " : " + ioe.getMessage());
397
			}
398
		} else {
399
			logMetacat.warn("Could not write out stored backup directory." 
400
					+ " User directory does not exist");
401
		}
402
	}
403

    
404
	/**
405
	 * Get the style skins directory. This is made up of the tomcat directory
406
	 * with context + file separator + "style" + file separator + "skins"
407
	 * 
408
	 * @return string holding the style skins directory
409
	 */
410
	public static String getStyleSkinsDir() throws PropertyNotFoundException {
411
		return getContextDir() + FileUtil.getFS() + "style" + FileUtil.getFS()
412
				+ "skins";
413
	}
414

    
415
	/**
416
	 * Get the SQL directory. This is made up of the context directory + file
417
	 * separator + sql
418
	 * 
419
	 * @return string holding the sql directory
420
	 */
421
	public static String getSQLDir() throws PropertyNotFoundException {
422
		return getContextDir() + FileUtil.getFS() + "WEB-INF" + FileUtil.getFS() + "sql";
423
	}
424

    
425
	/**
426
	 * Get the default style URL from metacat.properties.
427
	 * 
428
	 * @return string holding the default style URL
429
	 */
430
	public static String getDefaultStyleURL() throws PropertyNotFoundException {
431
		return getStyleCommonURL() + "/"
432
				+ PropertyService.getProperty("application.default-style");
433
	}
434

    
435
	/**
436
	 * Attempt to discover the deployment directory for this application. This is a
437
	 * best guess scenario. It is used by configuration routines before the
438
	 * deployment directory has been populated in metacat.properties. 
439
	 * 
440
	 * @param request
441
	 *            the http servlet request we will use to find the tomcat directory
442
	 * 
443
	 * @return a string holding the web application directory
444
	 */
445
	public static String discoverDeployDir(HttpServletRequest request) {
446
		ServletContext servletContext = request.getSession()
447
				.getServletContext();
448
		String realPath = servletContext.getRealPath(".");
449
		String contextPath = request.getContextPath();
450
		
451
		logMetacat.debug("realPath: " + realPath);
452
		logMetacat.debug("contextPath: " + contextPath);
453

    
454
		Pattern pattern = Pattern.compile(contextPath + "/\\.$");
455
		Matcher matcher = pattern.matcher(realPath);
456
		
457
		if (matcher.find()) {
458
			realPath = matcher.replaceFirst("");
459
		}
460
		
461
		return realPath;
462
	}
463
	
464
	/**
465
	 * Get the current user's home directory
466
	 * 
467
	 * @return a string holding the home directory
468
	 */
469
	public static String getUserHomeDir() {
470
		return System.getProperty("user.home");
471
	}
472

    
473
}
(11-11/12)