001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.server.util;
031:
032: import com.caucho.java.WorkDir;
033: import com.caucho.loader.EnvironmentLocal;
034: import com.caucho.util.Alarm;
035: import com.caucho.util.CharBuffer;
036: import com.caucho.util.CpuUsage;
037: import com.caucho.util.Crc64;
038: import com.caucho.vfs.CaseInsensitive;
039: import com.caucho.vfs.Path;
040: import com.caucho.vfs.Vfs;
041:
042: import java.io.File;
043: import java.io.IOException;
044: import java.net.InetAddress;
045: import java.util.logging.Level;
046: import java.util.logging.Logger;
047: import java.util.regex.Pattern;
048:
049: /**
050: * A wrapper for Caucho system variables, allowing tests to override
051: * the default variables.
052: */
053: public class CauchoSystem {
054: private static Logger log = Logger
055: .getLogger("com.caucho.util.CauchoSystem");
056:
057: static EnvironmentLocal<String> _serverIdLocal = new EnvironmentLocal<String>(
058: "caucho.server-id");
059:
060: static char _separatorChar = File.separatorChar;
061: static char _pathSeparatorChar = File.pathSeparatorChar;
062: static String _localHost;
063: static String _userDir;
064: static String _userName;
065: static Path _resinHome;
066: static Path _rootDirectory;
067: static boolean _isTesting;
068: static boolean _isTestWindows;
069:
070: static boolean _hasJni;
071:
072: private static int _isUnix = -1;
073: private static String _newline;
074: private static long _version;
075:
076: private static JniCauchoSystem _jniCauchoSystem;
077: private static boolean _isDetailedStatistics;
078: private static String _user;
079: private static String _group;
080: private static String _classPath;
081:
082: static CpuUsage _cpuUsage;
083:
084: private CauchoSystem() {
085: }
086:
087: /**
088: * Returns true if we're currently running a test.
089: */
090: public static boolean isTesting() {
091: return _isTesting;
092: }
093:
094: public static void setIsTesting(boolean testing) {
095: _isTesting = testing;
096: }
097:
098: /**
099: * Sets the Path to be used as ResinHome.
100: */
101: public static void setResinHome(Path path) {
102: _resinHome = path;
103: }
104:
105: /**
106: * Gets the Path used as ResinHome.
107: */
108: public static Path getResinHome() {
109: if (_resinHome != null)
110: return _resinHome;
111:
112: String path = System.getProperty("resin.home");
113: if (path != null) {
114: _resinHome = Vfs.lookupNative(path);
115: return _resinHome;
116: }
117:
118: String classpath = System.getProperty("java.class.path");
119: int head = 0;
120: char sep = getFileSeparatorChar();
121: char pathSep = sep == '/' ? ':' : ';';
122: while (path == null) {
123: int p = classpath.indexOf(pathSep, head);
124: String subpath;
125: if (p < 0)
126: subpath = classpath.substring(head);
127: else
128: subpath = classpath.substring(head, p);
129:
130: if (subpath.endsWith(sep + "lib" + sep + "resin.jar")
131: || subpath.equals("lib" + sep + "resin.jar")) {
132: path = subpath.substring(0, subpath.length()
133: - ("lib" + sep + "resin.jar").length());
134: }
135:
136: else if (subpath.endsWith(sep + "classes")
137: || subpath.equals("classes")) {
138: Path resinPath = Vfs.lookupNative(subpath);
139: resinPath = resinPath
140: .lookup("com/caucho/util/CauchoSystem.class");
141: if (resinPath.exists()) {
142: path = subpath.substring(0, subpath.length()
143: - "classes".length());
144: }
145: }
146:
147: if (p < 0)
148: break;
149: else
150: head = p + 1;
151: }
152:
153: if (path != null)
154: _resinHome = Vfs.lookupNative(path);
155: if (_resinHome != null && _resinHome.isDirectory())
156: return _resinHome;
157:
158: /*
159: String userHome = System.getProperty("user.home");
160: if (userHome != null)
161: resinHome = Pwd.lookupNative(userHome).lookup(".resin-home");
162:
163: if (resinHome != null && resinHome.isDirectory())
164: return resinHome;
165: */
166:
167: return Vfs.lookup();
168: }
169:
170: /**
171: * Gets the Path used as root directory
172: */
173: /**
174: public static Path getRootDirectory()
175: {
176: if (_rootDirectory != null)
177: return _rootDirectory;
178:
179: String path = System.getProperty("server.root");
180:
181: if (path != null) {
182: _rootDirectory = Vfs.lookupNative(path);
183: return _rootDirectory;
184: }
185:
186: path = System.getProperty("resin.home");
187:
188: if (path != null) {
189: _rootDirectory = Vfs.lookupNative(path);
190:
191: return _rootDirectory;
192: }
193:
194: _rootDirectory = getResinHome();
195:
196: return _rootDirectory;
197: }
198: */
199:
200: public static long getVersionId() {
201: if (_version == 0) {
202: _version = Crc64.generate(com.caucho.Version.FULL_VERSION);
203: }
204:
205: return _version;
206: }
207:
208: public static String getResinConfig() {
209: return getResinHome() + "/conf/resin.conf";
210: }
211:
212: /**
213: * Returns a path to the work directory. The work directory is
214: * specified in the resin.conf by /caucho.com/java/work-path. If
215: * unspecified, it defaults to /tmp/caucho.
216: *
217: * @return directory path to work in.
218: */
219: public static Path getWorkPath() {
220: Path workPath = WorkDir.getLocalWorkDir();
221:
222: if (workPath != null)
223: return workPath;
224:
225: String workDir;
226:
227: // Windows uses /temp as a work dir
228: if (isWindows())
229: workDir = "file:/c:/tmp/caucho";
230: else
231: workDir = "file:/tmp/caucho";
232:
233: Path path;
234: if (workDir.charAt(0) == '/')
235: path = Vfs.lookupNative(workDir);
236: else
237: path = CauchoSystem.getResinHome().lookupNative(workDir);
238: try {
239: path.mkdirs();
240: } catch (IOException e) {
241: }
242:
243: return path;
244: }
245:
246: public static String getServerId() {
247: return _serverIdLocal.get();
248: }
249:
250: public static String getUserDir() {
251: if (_userDir == null)
252: _userDir = System.getProperty("user.dir");
253:
254: return _userDir;
255: }
256:
257: public static char getFileSeparatorChar() {
258: return _separatorChar;
259: }
260:
261: public static char getPathSeparatorChar() {
262: return _pathSeparatorChar;
263: }
264:
265: public static String getNewlineString() {
266: if (_newline == null) {
267: Thread thread = Thread.currentThread();
268: ClassLoader oldLoader = thread.getContextClassLoader();
269:
270: try {
271: thread.setContextClassLoader(ClassLoader
272: .getSystemClassLoader());
273:
274: _newline = System.getProperty("line.separator");
275: if (_newline != null) {
276: } else if (isWindows())
277: _newline = "\r\n";
278: else
279: _newline = "\n";
280: } finally {
281: thread.setContextClassLoader(oldLoader);
282: }
283: }
284:
285: return _newline;
286: }
287:
288: public static boolean isWindows() {
289: return _separatorChar == '\\' || _isTestWindows;
290: }
291:
292: public static boolean isTest() {
293: return Alarm.isTest();
294: }
295:
296: public static boolean isCaseInsensitive() {
297: return CaseInsensitive.isCaseInsensitive();
298: }
299:
300: public static boolean isUnix() {
301: if (_isUnix >= 0)
302: return _isUnix == 1;
303:
304: _isUnix = 0;
305:
306: if (_separatorChar == '/' && Vfs.lookup("/bin/sh").canRead())
307: _isUnix = 1;
308:
309: return _isUnix == 1;
310: }
311:
312: public static void setWindowsTest(boolean isWindows) {
313: _isTesting = true;
314: _isTestWindows = isWindows;
315: Path.setTestWindows(isWindows);
316: }
317:
318: public static String getLocalHost() {
319: if (_localHost != null)
320: return _localHost;
321:
322: try {
323: InetAddress addr = InetAddress.getLocalHost();
324: _localHost = addr.getHostName();
325: } catch (Exception e) {
326: _localHost = "127.0.0.1";
327: }
328:
329: return _localHost;
330: }
331:
332: public static boolean isJdk15() {
333: try {
334: return Class.forName("java.lang.annotation.Annotation") != null;
335: } catch (Throwable e) {
336: return false;
337: }
338: }
339:
340: public static String getUserName() {
341: if (_userName == null)
342: _userName = System.getProperty("user.name");
343:
344: return _userName;
345: }
346:
347: /**
348: * Set true to cause the tracking of detailed statistcs, default false.
349: * Detailed statistics cause various parts of Resin to keep more detailed
350: * statistics at the possible expense of performance.
351: */
352: public static void setDetailedStatistics(boolean isVerboseStatistics) {
353: _isDetailedStatistics = isVerboseStatistics;
354: }
355:
356: /**
357: * Detailed statistics cause various parts of Resin to keep more detailed
358: * statistics at the possible expense of some performance.
359: */
360: public static boolean isDetailedStatistics() {
361: return _isDetailedStatistics;
362: }
363:
364: public static CpuUsage getCpuUsage() {
365: return CpuUsage.create();
366: }
367:
368: /**
369: * Loads a class from the context class loader.
370: *
371: * @param name the classname, separated by '.'
372: *
373: * @return the loaded class.
374: */
375: public static Class loadClass(String name)
376: throws ClassNotFoundException {
377: return loadClass(name, false, null);
378: }
379:
380: /**
381: * Loads a class from a classloader. If the loader is null, uses the
382: * context class loader.
383: *
384: * @param name the classname, separated by '.'
385: * @param init if true, resolves the class instances
386: * @param loader the class loader
387: *
388: * @return the loaded class.
389: */
390: public static Class loadClass(String name, boolean init,
391: ClassLoader loader) throws ClassNotFoundException {
392: if (loader == null)
393: loader = Thread.currentThread().getContextClassLoader();
394:
395: if (loader == null
396: || loader.equals(CauchoSystem.class.getClassLoader()))
397: return Class.forName(name);
398: else
399: return Class.forName(name, init, loader);
400: }
401:
402: /**
403: * Returns the system classpath, including the bootpath
404: */
405: public static String getClassPath() {
406: if (_classPath != null)
407: return _classPath;
408:
409: String cp = System.getProperty("java.class.path");
410:
411: String boot = System.getProperty("sun.boot.class.path");
412: if (boot != null && !boot.equals(""))
413: cp = cp + File.pathSeparatorChar + boot;
414:
415: Pattern pattern = Pattern.compile("" + File.pathSeparatorChar);
416:
417: String[] path = pattern.split(cp);
418:
419: CharBuffer cb = new CharBuffer();
420:
421: for (int i = 0; i < path.length; i++) {
422: Path subpath = Vfs.lookup(path[i]);
423:
424: if (subpath.canRead() || subpath.isDirectory()) {
425: if (cb.length() > 0)
426: cb.append(File.pathSeparatorChar);
427:
428: cb.append(path[i]);
429: }
430: }
431:
432: _classPath = cb.toString();
433:
434: return _classPath;
435: }
436:
437: public static double getLoadAvg() {
438: if (_jniCauchoSystem == null)
439: _jniCauchoSystem = JniCauchoSystem.create();
440:
441: return _jniCauchoSystem.getLoadAvg();
442: }
443:
444: /**
445: * Sets the runtime user so we don't need to run as root.
446: */
447: public static int setUser(String user, String group)
448: throws Exception {
449: _user = user;
450: _group = group;
451:
452: if (_hasJni && user != null)
453: return setUserNative(_user, _group);
454: else
455: return -1;
456: }
457:
458: private static native int setUserNative(String user, String group)
459: throws IOException;
460:
461: static {
462: try {
463: System.loadLibrary("resin");
464: _hasJni = true;
465: } catch (Throwable e) {
466: log.log(Level.FINE, e.toString(), e);
467: }
468: }
469: }
|