1 package org.gffs.application;
4 import java.io.IOException;
5 import java.net.URISyntaxException;
8 import org.apache.commons.logging.Log;
9 import org.apache.commons.logging.LogFactory;
10 import org.gffs.filesystem.FileSystemHelper;
13 * Some utility functions for getting information about the running application.
15 * @author Chris Koeritz
17 public class ProgramTools
19 public static Log _logger = LogFactory.getLog(ProgramTools.class);
22 * produces a list of the stack for a certain number of its elements, called stack frames. this will ignore the fact that this function is
23 * invoked, and start counting stack frames from the immediate caller's perspective (including it).
25 public static String showLastFewOnStack(int howManyFrames)
27 StackTraceElement[] elements = Thread.currentThread().getStackTrace();
28 StringBuilder toReturn = new StringBuilder();
30 * don't start at the very first frame; we want to skip backwards to the direct caller of this function.
33 int endFrame = Math.min(howManyFrames + 3, elements.length - 1);
34 for (int i = startFrame; i < endFrame; i++) {
35 if (toReturn.length() != 0) {
36 toReturn.append("\n<= ");
38 toReturn.append(getStackFrame(i));
40 return toReturn.toString();
44 * returns the Nth frame backwards starting from this function. 0 is this method, 1 is the invoker, 2 is the invoker's invoker, etc.
46 public static String getStackFrame(int which)
48 StackTraceElement[] elements = Thread.currentThread().getStackTrace();
49 /* a little self-protection to avoid accessing missing parts of the array. */
50 if (which >= elements.length)
51 which = elements.length - 1;
52 return elements[which].toString();
56 * returns the location where the code is running, as best as can be determined. finds the running location based on our jar files, or if
57 * that's not available, on the assumption of app path being within an appropriate installation (even if not at the top). this method
58 * cannot use standard genesis properties to look up the path, because this function needs to operate before anything else is loaded (for
61 static public String getInstallationDirectory()
63 String appPath = null;
64 // see if we can intuit our location from living in a jar.
65 URL url = ProgramTools.class.getProtectionDomain().getCodeSource().getLocation();
67 // get the app path but switch back slashes to forward ones.
68 appPath = new File(url.toURI().getSchemeSpecificPart()).toString().replace('\\', '/');
69 } catch (URISyntaxException e) {
70 String msg = "failed to convert code source url to app path: " + url;
72 throw new RuntimeException(msg);
74 if (_logger.isTraceEnabled())
75 _logger.trace("got source path as: " + appPath);
76 if (appPath.endsWith(".jar")) {
77 // we need to chop off the jar file part of the name.
78 int lastSlash = appPath.lastIndexOf("/");
80 // lastSlash = appPath.lastIndexOf("\\");
82 String msg = "could not find a slash character in the path: " + appPath;
84 throw new RuntimeException(msg);
86 appPath = appPath.substring(0, lastSlash);
87 if (_logger.isTraceEnabled())
88 _logger.trace("truncated path since inside jar: " + appPath);
90 appPath = appPath.concat("/..");
92 if (_logger.isTraceEnabled())
93 _logger.trace("jar-intuited startup bundle path: " + appPath);
95 File startupDir = new File(appPath);
96 if (!startupDir.exists() || !startupDir.isDirectory()) {
97 throw new RuntimeException(
98 "the location where we believe the installation is running from does not actually exist as a directory.");
101 //hmmm: below may not be very general since it does osgi? but it will work if people use a bundles dir.
104 * make sure we can find our own bundles directory, which is a crucial thing for osgi. if we can't find it, then we really don't know
107 File testingBundlesDir = new File(startupDir, "bundles");
108 File testingExtDir = new File(startupDir, "ext");
109 String lastStartupDirState = "not-equal"; // a string we should never see as a full path.
111 while (!testingBundlesDir.exists() || !testingExtDir.exists()) {
112 if (_logger.isDebugEnabled()) {
113 if (_logger.isTraceEnabled())
114 _logger.debug("failed to find bundles directory at '" + startupDir.getAbsolutePath() + "', popping up a level.");
117 if (lastStartupDirState.equals(FileSystemHelper.sanitizeFilename(startupDir.getAbsolutePath()))) {
118 throw new RuntimeException(
119 "caught the startup directory not changing, which means we have hit the root and failed to find our bundles and ext directories.");
121 // reset for next time.
122 lastStartupDirState = FileSystemHelper.sanitizeFilename(startupDir.getAbsolutePath());
124 // pop up a level, since we didn't find our bundles directory.
125 startupDir = new File(startupDir, "..");
126 testingBundlesDir = new File(startupDir, "bundles");
127 testingExtDir = new File(startupDir, "ext");
129 if (startupDir.getParent() == null) {
130 throw new RuntimeException("failed to find the bundles and ext directories after hitting top of file system paths.");
134 // we successfully found the bundles directory, even if we may have had to jump a few hoops.
135 if (_logger.isTraceEnabled()) {
136 _logger.debug("successfully found bundles directory under path: " + appPath);
139 // now resolve the path to an absolute location without relative components.
141 appPath = FileSystemHelper.sanitizeFilename(startupDir.getCanonicalPath());
142 } catch (IOException e) {
143 _logger.error("could not open osgi directory: " + appPath);
145 if (_logger.isTraceEnabled())
146 _logger.debug("startup path after resolution with File: " + appPath);