001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.system.server;
023:
024: import java.io.File;
025: import java.io.IOException;
026: import java.net.MalformedURLException;
027: import java.net.URL;
028: import java.util.Properties;
029:
030: import org.jboss.util.NestedRuntimeException;
031: import org.jboss.util.Null;
032: import org.jboss.util.Primitives;
033: import org.jboss.util.platform.Java;
034:
035: /**
036: * A container for the basic configuration elements required to create
037: * a Server instance.
038: *
039: * <p>MalformedURLException are rethrown as NestedRuntimeExceptions, so that
040: * code that needs to access these values does not have to directly
041: * worry about problems with lazy construction of final URL values.
042: *
043: * <p>Most values are determined durring first call to getter. All values
044: * when determined will have equivilent system properties set.
045: *
046: * <p>Clients are not meant to use this class directly. Instead use
047: * {@link ServerConfigLocator} to get an instance of {@link ServerConfig}
048: * and then use it to get the server's configuration bits.
049: *
050: * @jmx:mbean name="jboss.system:type=ServerConfig"
051: *
052: * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
053: * @author <a href="mailto:dimitris@jboss.org">Dimitris Andreadis</a>
054: * @author Scott.Stark@jboss.org
055: * @version <tt>$Revision: 59410 $</tt>
056: */
057: public class ServerConfigImpl implements ServerConfig,
058: ServerConfigImplMBean {
059: /** The configuration properties to pull data from. */
060: private Properties props;
061:
062: private File homeDir;
063: private URL homeURL;
064: private URL libraryURL;
065:
066: /**
067: * The base URL where patch files will be loaded from. This is
068: * typed as an Object to allow its value to contain Null.VALUE
069: * or a URL. If value is Null.VALUE then we have determined
070: * that there is no user configuration for this value and it will
071: * be passed back as null to the requesting client.
072: */
073: private Object patchURL;
074:
075: private String serverSpecificationVersion;
076:
077: private String serverName;
078: private File serverBaseDir;
079: private File serverHomeDir;
080: private File serverLogDir;
081: private File serverTempDir;
082: private File serverDataDir;
083: private URL serverBaseURL;
084: private URL serverHomeURL;
085: private URL serverLibraryURL;
086: private URL serverConfigURL;
087:
088: /** Exit on shutdown flag. */
089: private Boolean exitOnShutdown;
090: private Boolean blockingShutdown;
091: private Boolean requireJBossURLStreamHandlerFactory;
092: private Boolean platformMBeanServer;
093:
094: private String rootDeployableFilename;
095:
096: /**
097: * Construct a new <tt>ServerConfigImpl</tt> instance.
098: *
099: * @param props Configuration properties.
100: *
101: * @throws Exception Missing or invalid configuration.
102: */
103: public ServerConfigImpl(final Properties props) throws Exception {
104: this .props = props;
105:
106: // Must have HOME_DIR
107: homeDir = getFile(ServerConfig.HOME_DIR);
108: if (homeDir == null)
109: throw new Exception("Missing configuration value for: "
110: + ServerConfig.HOME_DIR);
111: System.setProperty(ServerConfig.HOME_DIR, homeDir.toString());
112: // Setup the SERVER_HOME_DIR system property
113: getServerHomeDir();
114:
115: Package this Package = getClass().getPackage();
116: serverSpecificationVersion = this Package
117: .getSpecificationVersion();
118: }
119:
120: /** Breakout the initialization of URLs from the constructor as we need
121: * the ServerConfig.HOME_DIR set for log setup, but we cannot create any
122: * file URLs prior to the
123: */
124: public void initURLs() throws MalformedURLException {
125: // If not set then default to homeDir
126: homeURL = getURL(ServerConfig.HOME_URL);
127: if (homeURL == null)
128: homeURL = homeDir.toURL();
129: System.setProperty(ServerConfig.HOME_URL, homeURL.toString());
130: }
131:
132: /////////////////////////////////////////////////////////////////////////
133: // Typed Access //
134: /////////////////////////////////////////////////////////////////////////
135:
136: /**
137: * Get the server Specification-Version
138: * @jmx:managed-attribute
139: */
140: public String getSpecificationVersion() {
141: return serverSpecificationVersion;
142: }
143:
144: /**
145: * Get the local home directory which the server is running from.
146: *
147: * @jmx:managed-attribute
148: */
149: public File getHomeDir() {
150: return homeDir;
151: }
152:
153: /**
154: * Get the home URL which the server is running from.
155: *
156: * @jmx:managed-attribute
157: */
158: public URL getHomeURL() {
159: return homeURL;
160: }
161:
162: /**
163: * Get the home URL which the server is running from.
164: *
165: * @jmx:managed-attribute
166: */
167: public URL getLibraryURL() {
168: if (libraryURL == null) {
169: try {
170: libraryURL = getURL(ServerConfig.LIBRARY_URL);
171: if (libraryURL == null) {
172: libraryURL = new URL(homeURL,
173: ServerConfig.LIBRARY_URL_SUFFIX);
174: }
175: System.setProperty(ServerConfig.LIBRARY_URL, libraryURL
176: .toString());
177: } catch (MalformedURLException e) {
178: throw new NestedRuntimeException(e);
179: }
180: }
181: return libraryURL;
182: }
183:
184: /**
185: * Get the patch URL for the server.
186: *
187: * @jmx:managed-attribute
188: */
189: public URL getPatchURL() {
190: if (patchURL == null) {
191: try {
192: patchURL = getURL(ServerConfig.PATCH_URL);
193: if (patchURL == null) {
194: patchURL = Null.VALUE;
195: } else {
196: System.setProperty(ServerConfig.PATCH_URL, patchURL
197: .toString());
198: }
199: } catch (MalformedURLException e) {
200: throw new NestedRuntimeException(e);
201: }
202: }
203:
204: if (patchURL == Null.VALUE)
205: return null;
206:
207: return (URL) patchURL;
208: }
209:
210: /**
211: * Get the name of the server.
212: *
213: * @jmx:managed-attribute
214: */
215: public String getServerName() {
216: if (serverName == null) {
217: serverName = props.getProperty(ServerConfig.SERVER_NAME,
218: ServerConfig.DEFAULT_SERVER_NAME);
219: System.setProperty(ServerConfig.SERVER_NAME, serverName);
220: }
221: return serverName;
222: }
223:
224: /**
225: * Get the base directory for calculating server home directories.
226: *
227: * @jmx:managed-attribute
228: */
229: public File getServerBaseDir() {
230: if (serverBaseDir == null) {
231: serverBaseDir = getFile(ServerConfig.SERVER_BASE_DIR);
232: if (serverBaseDir == null) {
233: serverBaseDir = new File(homeDir,
234: ServerConfig.SERVER_BASE_DIR_SUFFIX);
235: System.setProperty(ServerConfig.SERVER_BASE_DIR,
236: serverBaseDir.toString());
237: }
238: }
239: return serverBaseDir;
240: }
241:
242: /**
243: * Get the server home directory.
244: *
245: * @jmx:managed-attribute
246: */
247: public File getServerHomeDir() {
248: if (serverHomeDir == null) {
249: serverHomeDir = getFile(ServerConfig.SERVER_HOME_DIR);
250: if (serverHomeDir == null) {
251: serverHomeDir = new File(getServerBaseDir(),
252: getServerName());
253: System.setProperty(ServerConfig.SERVER_HOME_DIR,
254: serverHomeDir.toString());
255: }
256: }
257: return serverHomeDir;
258: }
259:
260: /**
261: * Get the directory where temporary files will be stored. The associated
262: * ServerConfig.SERVER_LOG_DIR system property needs to be set before
263: * the logging framework is used.
264: *
265: * @see ServerConfig.SERVER_LOG_DIR
266: * @return the writable temp directory
267: */
268: public File getServerLogDir() {
269: if (serverLogDir == null) {
270: serverLogDir = getFile(ServerConfig.SERVER_LOG_DIR);
271: if (serverLogDir == null) {
272: serverLogDir = new File(getServerHomeDir(),
273: ServerConfig.SERVER_LOG_DIR_SUFFIX);
274: System.setProperty(ServerConfig.SERVER_LOG_DIR,
275: serverLogDir.toString());
276: }
277: }
278: return serverLogDir;
279: }
280:
281: /**
282: * Get the directory where temporary files will be stored.
283: *
284: * @jmx:managed-attribute
285: * @return the writable temp directory
286: */
287: public File getServerTempDir() {
288: if (serverTempDir == null) {
289: serverTempDir = getFile(ServerConfig.SERVER_TEMP_DIR);
290: if (serverTempDir == null) {
291: serverTempDir = new File(getServerHomeDir(),
292: ServerConfig.SERVER_TEMP_DIR_SUFFIX);
293: System.setProperty(ServerConfig.SERVER_TEMP_DIR,
294: serverTempDir.toString());
295: }
296: }
297: return serverTempDir;
298: }
299:
300: /**
301: * Get the directory where local data will be stored.
302: *
303: * @jmx:managed-attribute
304: * @return the data directory
305: */
306: public File getServerDataDir() {
307: if (serverDataDir == null) {
308: serverDataDir = getFile(ServerConfig.SERVER_DATA_DIR);
309: if (serverDataDir == null) {
310: serverDataDir = new File(getServerHomeDir(),
311: ServerConfig.SERVER_DATA_DIR_SUFFIX);
312: System.setProperty(ServerConfig.SERVER_DATA_DIR,
313: serverDataDir.toString());
314: }
315: }
316: return serverDataDir;
317: }
318:
319: /**
320: * Get the native dir for unpacking
321: *
322: * @jmx:managed-attribute
323: * @return the directory
324: */
325: public File getServerNativeDir() {
326: String fileName = System.getProperty(NATIVE_DIR_PROPERTY);
327: if (fileName != null)
328: return new File(fileName);
329: return new File(getServerTempDir(), "native");
330: }
331:
332: /**
333: * Get the temporary deployment dir for unpacking
334: *
335: * @jmx:managed-attribute
336: * @return the directory
337: */
338: public File getServerTempDeployDir() {
339: return new File(getServerTempDir(), "deploy");
340: }
341:
342: /**
343: * Get the base directory for calculating server home URLs.
344: *
345: * @jmx:managed-attribute
346: */
347: public URL getServerBaseURL() {
348: if (serverBaseURL == null) {
349: try {
350: serverBaseURL = getURL(ServerConfig.SERVER_BASE_URL);
351: if (serverBaseURL == null) {
352: serverBaseURL = new URL(homeURL,
353: ServerConfig.SERVER_BASE_URL_SUFFIX);
354: }
355: System.setProperty(ServerConfig.SERVER_BASE_URL,
356: serverBaseURL.toString());
357: } catch (MalformedURLException e) {
358: throw new NestedRuntimeException(e);
359: }
360: }
361: return serverBaseURL;
362: }
363:
364: /**
365: * Get the server home URL.
366: *
367: * @jmx:managed-attribute
368: */
369: public URL getServerHomeURL() {
370: if (serverHomeURL == null) {
371: try {
372: serverHomeURL = getURL(ServerConfig.SERVER_HOME_URL);
373: if (serverHomeURL == null) {
374: serverHomeURL = new URL(getServerBaseURL(),
375: getServerName() + "/");
376: }
377: System.setProperty(ServerConfig.SERVER_HOME_URL,
378: serverHomeURL.toString());
379: } catch (MalformedURLException e) {
380: throw new NestedRuntimeException(e);
381: }
382: }
383: return serverHomeURL;
384: }
385:
386: /**
387: * Get the server library URL.
388: *
389: * @jmx:managed-attribute
390: */
391: public URL getServerLibraryURL() {
392: if (serverLibraryURL == null) {
393: try {
394: serverLibraryURL = getURL(ServerConfig.SERVER_LIBRARY_URL);
395: if (serverLibraryURL == null) {
396: serverLibraryURL = new URL(getServerHomeURL(),
397: ServerConfig.LIBRARY_URL_SUFFIX);
398: }
399: System.setProperty(ServerConfig.SERVER_LIBRARY_URL,
400: serverLibraryURL.toString());
401: } catch (MalformedURLException e) {
402: throw new NestedRuntimeException(e);
403: }
404: }
405: return serverLibraryURL;
406: }
407:
408: /**
409: * Get the server configuration URL.
410: *
411: * @jmx:managed-attribute
412: */
413: public URL getServerConfigURL() {
414: if (serverConfigURL == null) {
415: try {
416: serverConfigURL = getURL(ServerConfig.SERVER_CONFIG_URL);
417: if (serverConfigURL == null) {
418: serverConfigURL = new URL(getServerHomeURL(),
419: ServerConfig.SERVER_CONFIG_URL_SUFFIX);
420: }
421: System.setProperty(ServerConfig.SERVER_CONFIG_URL,
422: serverConfigURL.toString());
423: } catch (MalformedURLException e) {
424: throw new NestedRuntimeException(e);
425: }
426: }
427: return serverConfigURL;
428: }
429:
430: /**
431: * Get the current value of the flag that indicates if we are
432: * using the platform MBeanServer as the main jboss server.
433: * Both the {@link ServerConfig.PLATFORM_MBEANSERVER}
434: * property must be set, and the jvm must be jdk1.5+
435: *
436: * @return true if jboss runs on the jvm platfrom MBeanServer
437: *
438: * @jmx:managed-attribute
439: */
440: public boolean getPlatformMBeanServer() {
441: if (platformMBeanServer == null) {
442: if (Java.isCompatible(Java.VERSION_1_5)) {
443: // get whatever the user has specified or the default
444: String value = props
445: .getProperty(
446: ServerConfig.PLATFORM_MBEANSERVER,
447: (new Boolean(
448: ServerConfig.DEFAULT_PLATFORM_MBEANSERVER))
449: .toString());
450:
451: // treat empty string as true
452: value = "".equals(value) ? "true" : value;
453:
454: // true or false
455: platformMBeanServer = new Boolean(value);
456: } else {
457: // negative :)
458: platformMBeanServer = Boolean.FALSE;
459: }
460: }
461: return platformMBeanServer.booleanValue();
462: }
463:
464: /**
465: * Enable or disable exiting the JVM when {@link Server#shutdown} is called.
466: * If enabled, then shutdown calls {@link Server#exit}. If disabled, then
467: * only the shutdown hook will be run.
468: *
469: * @param flag True to enable calling exit on shutdown.
470: *
471: * @jmx:managed-attribute
472: */
473: public void setExitOnShutdown(final boolean flag) {
474: exitOnShutdown = Primitives.valueOf(flag);
475: }
476:
477: /**
478: * Get the current value of the exit on shutdown flag.
479: *
480: * @return The current value of the exit on shutdown flag.
481: *
482: * @jmx:managed-attribute
483: */
484: public boolean getExitOnShutdown() {
485: if (exitOnShutdown == null) {
486: String value = props.getProperty(
487: ServerConfig.EXIT_ON_SHUTDOWN, null);
488: if (value == null) {
489: exitOnShutdown = Primitives
490: .valueOf(ServerConfig.DEFAULT_EXIT_ON_SHUTDOWN);
491: } else {
492: exitOnShutdown = new Boolean(value);
493: }
494: }
495: return exitOnShutdown.booleanValue();
496: }
497:
498: /**
499: * Enable or disable blocking when {@link Server#shutdown} is
500: * called. If enabled, then shutdown will be called in the current
501: * thread. If disabled, then the shutdown hook will be run
502: * ansynchronously in a separate thread.
503: *
504: * @param flag True to enable blocking shutdown.
505: *
506: * @jmx:managed-attribute
507: */
508: public void setBlockingShutdown(final boolean flag) {
509: blockingShutdown = Primitives.valueOf(flag);
510: }
511:
512: /**
513: * Get the current value of the blocking shutdown flag.
514: *
515: * @return The current value of the blocking shutdown flag.
516: *
517: * @jmx:managed-attribute
518: */
519: public boolean getBlockingShutdown() {
520: if (blockingShutdown == null) {
521: String value = props.getProperty(
522: ServerConfig.BLOCKING_SHUTDOWN, null);
523: if (value == null) {
524: blockingShutdown = Primitives
525: .valueOf(ServerConfig.DEFAULT_BLOCKING_SHUTDOWN);
526: } else {
527: blockingShutdown = new Boolean(value);
528: }
529: }
530: return blockingShutdown.booleanValue();
531: }
532:
533: /**
534: * Set the RequireJBossURLStreamHandlerFactory flag. if false,
535: * exceptions when setting the URLStreamHandlerFactory will be
536: * logged and ignored.
537: *
538: * @param flag True to enable blocking shutdown.
539: *
540: * @jmx:managed-attribute
541: */
542: public void setRequireJBossURLStreamHandlerFactory(
543: final boolean flag) {
544: requireJBossURLStreamHandlerFactory = Primitives.valueOf(flag);
545: }
546:
547: /**
548: * Get the current value of the requireJBossURLStreamHandlerFactory flag.
549: *
550: * @return The current value of the requireJBossURLStreamHandlerFactory flag.
551: *
552: * @jmx:managed-attribute
553: */
554: public boolean getRequireJBossURLStreamHandlerFactory() {
555: if (requireJBossURLStreamHandlerFactory == null) {
556: String value = props
557: .getProperty(
558: ServerConfig.REQUIRE_JBOSS_URL_STREAM_HANDLER_FACTORY,
559: null);
560: if (value == null) {
561: requireJBossURLStreamHandlerFactory = Primitives
562: .valueOf(ServerConfig.DEFAULT_REQUIRE_JBOSS_URL_STREAM_HANDLER_FACTORY);
563: } else {
564: requireJBossURLStreamHandlerFactory = new Boolean(value);
565: }
566: }
567: return requireJBossURLStreamHandlerFactory.booleanValue();
568: }
569:
570: /**
571: * Set the filename of the root deployable that will be used to finalize
572: * the bootstrap process.
573: *
574: * @param filename The filename of the root deployable.
575: *
576: * @jmx:managed-attribute
577: */
578: public void setRootDeploymentFilename(final String filename) {
579: this .rootDeployableFilename = filename;
580: }
581:
582: /**
583: * Get the filename of the root deployable that will be used to finalize
584: * the bootstrap process.
585: *
586: * @return The filename of the root deployable.
587: *
588: * @jmx:managed-attribute
589: */
590: public String getRootDeploymentFilename() {
591: if (rootDeployableFilename == null) {
592: rootDeployableFilename = props.getProperty(
593: ServerConfig.ROOT_DEPLOYMENT_FILENAME,
594: ServerConfig.DEFAULT_ROOT_DEPLOYMENT_FILENAME);
595: }
596:
597: return rootDeployableFilename;
598: }
599:
600: /**
601: * Get a URL from configuration.
602: */
603: private URL getURL(final String name) throws MalformedURLException {
604: String value = props.getProperty(name, null);
605: if (value != null) {
606: if (!value.endsWith("/"))
607: value += "/";
608: return new URL(value);
609: }
610:
611: return null;
612: }
613:
614: /**
615: * Get a File from configuration.
616: * @return the CanonicalFile form for the given name.
617: */
618: private File getFile(final String name) {
619: String value = props.getProperty(name, null);
620: if (value != null) {
621: try {
622: File f = new File(value);
623: return f.getCanonicalFile();
624: } catch (IOException e) {
625: return new File(value);
626: }
627: }
628:
629: return null;
630: }
631: }
|