001: /******************************************************************************
002: * LPS.java
003: * ****************************************************************************/package org.openlaszlo.server;
004:
005: import java.lang.Package;
006: import java.lang.Class;
007: import java.util.Calendar;
008: import java.util.Locale;
009: import java.util.Properties;
010: import java.io.*;
011: import java.net.*;
012: import javax.servlet.*;
013: import javax.servlet.ServletConfig.*;
014: import javax.servlet.http.*;
015: import org.openlaszlo.utils.ChainedException;
016: import org.openlaszlo.utils.MathUtils;
017: import org.openlaszlo.utils.LZUtils;
018:
019: import org.apache.log4j.*;
020:
021: import org.jdom.*;
022: import org.jdom.input.SAXBuilder;
023: import org.jdom.filter.ElementFilter;
024: import org.jdom.input.*;
025:
026: /**
027: * LPS is a singleton for global server state.
028: *
029: * @author Eric Bloch
030: * @version 1.0
031: */
032: public class LPS {
033:
034: private static long mBootTime = Calendar.getInstance().getTime()
035: .getTime();
036:
037: private static Properties mProperties = null;
038:
039: private static String mHome = null;
040:
041: public static Configuration configuration = null;
042:
043: public static String VERSION_FILE = "/org/openlaszlo/server/lps.xml";
044:
045: public static String mDefaultRuntime = "swf8";
046:
047: private static String mBuildID;
048: private static String mBuildDate;
049: private static String mVersionID;
050: private static String mRelease;
051:
052: public static String mSWFVersionDefault = null;
053: public static int mSWFVersionNumDefault = -1;
054:
055: private static Locale mLocale = null; /* for i18n */
056:
057: /**
058: * Initialize version info
059: */
060: static {
061: // Read in version details from XML file
062: SAXBuilder builder = new SAXBuilder();
063: Document doc;
064: try {
065: InputStream in = LPS.class
066: .getResourceAsStream(VERSION_FILE);
067: doc = builder.build(in);
068: } catch (Throwable t) {
069: throw new RuntimeException(t);
070: }
071: Element root = doc.getRootElement();
072: mBuildID = root.getChildTextNormalize("build-id");
073: mBuildDate = root.getChildTextNormalize("build-date");
074: mVersionID = root.getChildTextNormalize("version-id");
075: mRelease = root.getChildTextNormalize("release");
076: }
077:
078: /*
079: * Set the home directory
080: */
081: public static void setHome(String home) {
082: mHome = home;
083: }
084:
085: /*
086: * Read the xml configuration file.
087: */
088: public static void initialize() {
089: configuration = new Configuration();
090: }
091:
092: /**
093: * @return the LPS_HOME property
094: */
095: public static String HOME() {
096: if (mHome == null || mHome.equals("")) {
097: mHome = getSystemProperty("LPS_HOME");
098: if (mHome == null || mHome.equals("")) {
099: // This is catastrophic
100: throw new RuntimeException(
101: /* (non-Javadoc)
102: * @i18n.test
103: * @org-mes="Server configuration error: can't find LPS_HOME."
104: */
105: org.openlaszlo.i18n.LaszloMessages.getMessage(LPS.class
106: .getName(), "051018-110"));
107: }
108: }
109: return mHome;
110: }
111:
112: /**
113: * @return the directory which is the parent of the directory in the LPS_HOME property
114: */
115: public static String getHomeParent() {
116: File myfile = new File(LPS.HOME());
117: return (myfile.getParent());
118: }
119:
120: /**
121: * @return the "root directory" of the LPS bits. Typically, HOME/WEB-INF/lps.
122: */
123: public static String ROOT() {
124: return HOME() + File.separator + "WEB-INF" + File.separator
125: + "lps";
126: }
127:
128: /**
129: * @return the "public root directory" of the LPS bits. Typically, HOME/lps.
130: */
131: public static String PUBLIC_ROOT() {
132: return HOME() + File.separator + "lps";
133: }
134:
135: /**
136: * @return the location of the lps.jar when
137: * running inside a servlet container
138: */
139: public static File getLPSJarFile() {
140: return new File(HOME() + File.separator + "WEB-INF"
141: + File.separator + "lib" + File.separator + "lps.jar");
142: }
143:
144: /**
145: * @return the location of the config directory.
146: */
147: public static String getConfigDirectory() {
148: return ConfigDir.get(HOME());
149: }
150:
151: /**
152: * @return the properties file
153: */
154: // TODO:[2002-12-2 bloch] add parameter/property for
155: // location of properties file.
156: public static File getPropertiesFile() {
157: return new File(getConfigDirectory() + File.separator
158: + "lps.properties");
159: }
160:
161: /**
162: * @return the location of the default cache directory.
163: */
164: public static String getWorkDirectory() {
165: return ROOT() + File.separator + "work";
166: }
167:
168: /**
169: * @return the location of the misc directory.
170: */
171: public static String getMiscDirectory() {
172: return ROOT() + File.separator + "misc";
173: }
174:
175: /**
176: * @return the location of the images directory.
177: */
178: public static String getImagesDirectory() {
179: return ROOT() + File.separator + "images";
180: }
181:
182: /**
183: * @return the location of the components directory.
184: */
185: public static String getComponentsDirectory() {
186: return PUBLIC_ROOT() + File.separator + "components";
187: }
188:
189: /**
190: * @return the location of the fonts directory.
191: */
192: public static String getFontDirectory() {
193: return PUBLIC_ROOT() + File.separator + "fonts";
194: }
195:
196: /*
197: * @return the location of the lfc directory
198: */
199: public static String getLFCDirectory() {
200: return HOME()
201: + File.separator
202: + LPS.getProperty("compiler.runtime.dir").replace('/',
203: File.separatorChar);
204: }
205:
206: public static String getLFCname(String runtime, boolean debug,
207: boolean profile, boolean backtrace) {
208: String lfc = "LFC";
209: String extension = "js";
210: if (runtime == null) {
211: runtime = getRuntimeDefault();
212: }
213:
214: if (runtime.indexOf("swf") == 0) {
215: runtime = runtime.substring("swf".length());
216: extension = "lzl";
217: }
218:
219: lfc += runtime;
220:
221: if (profile) {
222: lfc += "-profile";
223: }
224:
225: if (backtrace) {
226: lfc += "-backtrace";
227: } else if (debug) {
228: lfc += "-debug";
229: }
230:
231: return lfc + "." + extension;
232: }
233:
234: /*
235: * @return the location of the server template directory
236: */
237: public static String getTemplateDirectory() {
238: return ROOT() + File.separator + "templates";
239: }
240:
241: /**
242: * @return a string representation of the version
243: * of this build.
244: */
245: public static String getBuild() {
246: // The version number is actually baked into the manifest for the
247: // of the package.
248:
249: /* This doesn't work under Tomcat3.3 (see bug 4948, erroneous closed)
250: try {
251: Package p = Package.getPackage("org.openlaszlo.server");
252: return p.getImplementationVersion();
253: } catch (Exception e) {
254: // THIS IS FATAL!
255: throw new RuntimeException(e);
256: }
257: */
258:
259: return mBuildID;
260: }
261:
262: /**
263: * @return a string representation of the version
264: * of this build.
265: */
266: public static String getVersion() {
267: // The version number is actually baked into the manifest for the
268: // of the package.
269:
270: /* This doesn't work under Tomcat3.3 (see bug 4948, erroneous closed)
271: try {
272: Package p = Package.getPackage("org.openlaszlo.server");
273: return p.getSpecificationVersion();
274: } catch (Exception e) {
275: // THIS IS FATAL!
276: throw new RuntimeException(e);
277: }
278: */
279:
280: return mVersionID;
281: }
282:
283: /**
284: * @return a string representation of the release
285: */
286: public static String getRelease() {
287: // The version number is actually baked into the manifest for the
288: // of the package.
289:
290: /* This doesn't work under Tomcat3.3 (see bug 4948, erroneous closed)
291: try {
292: Package p = Package.getPackage("org.openlaszlo.server");
293: return p.getSpecificationVersion();
294: } catch (Exception e) {
295: // THIS IS FATAL!
296: throw new RuntimeException(e);
297: }
298: */
299:
300: return mRelease;
301: }
302:
303: /*
304: * @return the string version of the LPS in lowercase. E.g. lps-dr, lps-v1.
305: */
306: public static String getShortVersion() {
307: return "lps-" + mVersionID;
308: }
309:
310: /**
311: * @return the boot time
312: */
313: public static long getBootTime() {
314: return mBootTime;
315: }
316:
317: /**
318: *
319: */
320: public static String getBuildDate() {
321: return mBuildDate;
322: }
323:
324: /**
325: * Set SWF version default.
326: */
327: public static void setRuntimeDefault(String runtime) {
328: mDefaultRuntime = runtime;
329: if (runtime.equals("swf8")) {
330: mSWFVersionNumDefault = 8;
331: mSWFVersionDefault = "swf8";
332: } else if (runtime.equals("swf7")) {
333: mSWFVersionNumDefault = 7;
334: mSWFVersionDefault = "swf7";
335: }
336: }
337:
338: public static String getRuntimeDefault() {
339: return LPS.getProperty("compiler.runtime.default",
340: mDefaultRuntime);
341: }
342:
343: /**
344: * @return swf version number
345: */
346: public static int getSWFVersionNum(String swfversion) {
347: if (swfversion == null)
348: return mSWFVersionNumDefault;
349: if (swfversion.equals("swf8"))
350: return 8;
351: if (swfversion.equals("swf7"))
352: return 7;
353: if (swfversion.equals("swf6"))
354: return 6;
355: if (swfversion.equals("swf5"))
356: return 5;
357: return mSWFVersionNumDefault;
358: }
359:
360: public static String getSWFVersion(int num) {
361: if (num == 8)
362: return "swf8";
363: if (num == 7)
364: return "swf7";
365: if (num == 6)
366: return "swf6";
367: if (num == 5)
368: return "swf5";
369: return mSWFVersionDefault;
370: }
371:
372: /**
373: * @return swf version number
374: */
375: public static int getSWFVersionNum(HttpServletRequest req) {
376: return getSWFVersionNum(req.getParameter("lzr"));
377: }
378:
379: /**
380: * @return an XML string of info
381: */
382: public static String getInfo(HttpServletRequest req,
383: ServletContext ctxt, String tagName) {
384: StringBuffer buf = new StringBuffer();
385:
386: InetAddress localHost;
387: InetAddress[] myIPs;
388:
389: final double MEG = 1024 * 1024;
390:
391: // Store my ips
392: try {
393: localHost = InetAddress.getLocalHost();
394: } catch (UnknownHostException e) {
395: throw new ChainedException(
396: /* (non-Javadoc)
397: * @i18n.test
398: * @org-mes="LPS can't determine localhost ip address"
399: */
400: org.openlaszlo.i18n.LaszloMessages.getMessage(LPS.class
401: .getName(), "051019-357"));
402: }
403: try {
404: myIPs = InetAddress.getAllByName("localhost");
405: } catch (UnknownHostException e) {
406: throw new ChainedException(
407: /* (non-Javadoc)
408: * @i18n.test
409: * @org-mes="Can not determine server IP address!"
410: */
411: org.openlaszlo.i18n.LaszloMessages.getMessage(LPS.class
412: .getName(), "051019-369"));
413: }
414:
415: buf.append("<").append(tagName).append(" \n");
416: buf.append("\t server-port=\"" + req.getServerPort() + "\"\n");
417: buf.append("\t servlet-container=\"" + ctxt.getServerInfo()
418: + "\"\n");
419: buf.append("\t servlet-container-version=\""
420: + ctxt.getMajorVersion() + "." + ctxt.getMinorVersion()
421: + "\"\n");
422: // buf.append("\t context=\"" + ctxt + "\"\n");
423: buf.append("\t jre-version=\""
424: + getSystemPropertyOrUnknowable("java.version")
425: + "\"\n");
426: buf.append("\t os-name=\""
427: + getSystemPropertyOrUnknowable("os.name") + "\"\n");
428: buf.append("\t os-version=\""
429: + getSystemPropertyOrUnknowable("os.version") + "\"\n");
430: String level = "org.openlaszlo logger not configured!";
431: Logger l = Logger.getLogger("org.openlaszlo");
432: try {
433: if (l != null) {
434: level = Logger.getLogger("org.openlaszlo").getLevel()
435: .toString();
436: }
437: } catch (Throwable t) {
438: level = "unknown";
439: }
440: buf.append("\t log4j-level=\"" + level + "\"\n");
441: buf.append("\t user=\""
442: + getSystemPropertyOrUnknowable("user.name") + "\"\n");
443: buf.append("\t version=\"" + getVersion() + "\"\n");
444: buf.append("\t release=\"" + getRelease() + "\"\n");
445: buf.append("\t build=\"" + getBuild() + "\"\n");
446: buf.append("\t built-on=\"" + mBuildDate + "\"\n");
447: buf.append("\t max-mem=\""
448: + MathUtils.formatDouble(Runtime.getRuntime()
449: .maxMemory()
450: / (MEG), 2) + "MB\"\n");
451: buf.append("\t total-mem=\""
452: + MathUtils.formatDouble(Runtime.getRuntime()
453: .totalMemory()
454: / (MEG), 2) + "MB\"\n");
455: buf.append("\t free-mem=\""
456: + MathUtils.formatDouble(Runtime.getRuntime()
457: .freeMemory()
458: / (MEG), 2) + "MB\"\n");
459: buf.append("\t lps-home=\"" + mHome + "\"\n");
460: buf.append("\t localhost=\"" + localHost.getHostAddress()
461: + "\"\n");
462: for (int i = 0; i < myIPs.length; i++) {
463: buf.append("\t ipaddress-" + (i + 1) + "=\""
464: + myIPs[i].getHostAddress() + "\"\n");
465: }
466: buf.append("\t client=\"" + req.getRemoteHost() + "\"\n");
467: buf.append("\t locale=\"" + getLocale().toString() + "\"\n");
468: buf.append("/>");
469:
470: // TODO: [2003-02-28 bloch] add lps.properties fia properties->xml thingee
471:
472: return buf.toString();
473: }
474:
475: /**
476: * Safe version of System.getProperty() that won't
477: * throw a SecurityException if the property can't be read
478: */
479: public static String getSystemProperty(String name) {
480: try {
481: return System.getProperty(name);
482: } catch (SecurityException e) {
483: // TODO [2004-07-06 bloch]: log the failure somehow
484: return "";
485: }
486: }
487:
488: /**
489: * Safe version of System.getProperty() that won't
490: * throw a SecurityException if the property can't be read.
491: * Return 'unknowable' if security won't let us know.
492: */
493: public static String getSystemPropertyOrUnknowable(String name) {
494: return getSystemProperty(name, "unknowable");
495: }
496:
497: /**
498: * Safe version of System.getProperty() that won't
499: * throw a SecurityException if the property can't be read
500: */
501: public static String getSystemProperty(String name, String d) {
502: try {
503: return System.getProperty(name, d);
504: } catch (SecurityException e) {
505: // TODO [2004-07-06 bloch]: log the failure somehow
506: return d;
507: }
508: }
509:
510: private static void loadProperties() {
511: if (mProperties == null) {
512: File propFile = getPropertiesFile();
513: Properties properties = new Properties();
514: Properties sysProperties = (Properties) System
515: .getProperties().clone();
516: try {
517: properties.load(new FileInputStream(propFile));
518: properties = LZUtils.expandProperties(properties);
519: sysProperties.putAll(properties);
520:
521: } catch (Exception e) {
522: throw new ChainedException(e);
523: }
524: mProperties = sysProperties;
525: }
526: }
527:
528: /** @return the LPS properties */
529: public static Properties getProperties() {
530: loadProperties();
531: return mProperties;
532: }
533:
534: /** @return a property from the LPS property file, defaulting
535: * to value. */
536: public static String getProperty(String name, String value) {
537: loadProperties();
538: return mProperties.getProperty(name, value);
539: }
540:
541: /** @return a property from the LPS property file. */
542: public static String getProperty(String name) {
543: loadProperties();
544: return getProperty(name, null);
545: }
546:
547: /** Override a property in the LPS property file. */
548: public static void setProperty(String name, String value) {
549: loadProperties();
550: mProperties.setProperty(name, value);
551: }
552:
553: public static boolean isInternalBuild() {
554: return LPS.getBuild().equals("INTERNAL");
555: }
556:
557: /**
558: * @return the LOCALE property
559: */
560: public static Locale getLocale() {
561: if (mLocale == null) {
562: /* get "i18n.LOCALE" from lps.properties */
563: mLocale = new Locale(LPS.getProperty("i18n.locale",
564: "NO_LOCALE"));
565: }
566: return mLocale;
567: }
568: }
|