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.loader;
031:
032: import com.caucho.lifecycle.StartLifecycleException;
033: import com.caucho.server.util.CauchoSystem;
034: import com.caucho.vfs.Depend;
035: import com.caucho.vfs.Dependency;
036: import com.caucho.vfs.Path;
037:
038: import java.security.Permission;
039: import java.util.ArrayList;
040:
041: /**
042: * Static utility classes.
043: */
044: public class Environment {
045: private static ArrayList<EnvironmentListener> _globalEnvironmentListeners = new ArrayList<EnvironmentListener>();
046:
047: private static ArrayList<ClassLoaderListener> _globalLoaderListeners = new ArrayList<ClassLoaderListener>();
048:
049: /**
050: * Returns the local environment.
051: */
052: public static EnvironmentClassLoader getEnvironmentClassLoader() {
053: ClassLoader loader = Thread.currentThread()
054: .getContextClassLoader();
055:
056: for (; loader != null; loader = loader.getParent()) {
057: if (loader instanceof EnvironmentClassLoader)
058: return (EnvironmentClassLoader) loader;
059: }
060:
061: return null;
062: }
063:
064: /**
065: * Returns the local environment.
066: */
067: public static EnvironmentClassLoader getEnvironmentClassLoader(
068: ClassLoader loader) {
069: for (; loader != null; loader = loader.getParent()) {
070: if (loader instanceof EnvironmentClassLoader)
071: return (EnvironmentClassLoader) loader;
072: }
073:
074: return null;
075: }
076:
077: /**
078: * Add listener.
079: *
080: * @param listener object to listen for environment start/stop
081: */
082: public static void addEnvironmentListener(
083: EnvironmentListener listener) {
084: ClassLoader loader = Thread.currentThread()
085: .getContextClassLoader();
086:
087: addEnvironmentListener(listener, loader);
088: }
089:
090: /**
091: * Add listener.
092: *
093: * @param listener object to listen for environment create/destroy
094: * @param loader the context class loader
095: */
096: public static void addEnvironmentListener(
097: EnvironmentListener listener, ClassLoader loader) {
098: for (; loader != null; loader = loader.getParent()) {
099: if (loader instanceof EnvironmentClassLoader) {
100: ((EnvironmentClassLoader) loader).addListener(listener);
101: return;
102: }
103: }
104:
105: _globalEnvironmentListeners.add(listener);
106: }
107:
108: /**
109: * Remove listener.
110: *
111: * @param listener object to listen for environment start/stop
112: */
113: public static void removeEnvironmentListener(
114: EnvironmentListener listener) {
115: ClassLoader loader = Thread.currentThread()
116: .getContextClassLoader();
117:
118: removeEnvironmentListener(listener, loader);
119: }
120:
121: /**
122: * Remove listener.
123: *
124: * @param listener object to listen for environment create/destroy
125: * @param loader the context class loader
126: */
127: public static void removeEnvironmentListener(
128: EnvironmentListener listener, ClassLoader loader) {
129: for (; loader != null; loader = loader.getParent()) {
130: if (loader instanceof EnvironmentClassLoader) {
131: ((EnvironmentClassLoader) loader)
132: .removeListener(listener);
133: return;
134: }
135: }
136:
137: _globalEnvironmentListeners.remove(listener);
138: }
139:
140: /**
141: * Add listener.
142: *
143: * @param listener object to listen for environment create/destroy
144: * @param loader the context class loader
145: */
146: public static void addChildEnvironmentListener(
147: EnvironmentListener listener) {
148: ClassLoader loader = Thread.currentThread()
149: .getContextClassLoader();
150:
151: addChildEnvironmentListener(listener, loader);
152: }
153:
154: /**
155: * Add listener.
156: *
157: * @param listener object to listen for environment create/destroy
158: * @param loader the context class loader
159: */
160: public static void addChildEnvironmentListener(
161: EnvironmentListener listener, ClassLoader loader) {
162: for (; loader != null; loader = loader.getParent()) {
163: if (loader instanceof EnvironmentClassLoader) {
164: ((EnvironmentClassLoader) loader)
165: .addChildListener(listener);
166: return;
167: }
168: }
169: }
170:
171: /**
172: * Add listener.
173: *
174: * @param listener object to listen for environment create/destroy
175: * @param loader the context class loader
176: */
177: public static void addChildLoaderListener(AddLoaderListener listener) {
178: ClassLoader loader = Thread.currentThread()
179: .getContextClassLoader();
180:
181: addChildLoaderListener(listener, loader);
182: }
183:
184: /**
185: * Add listener.
186: *
187: * @param listener object to listen for environment create/destroy
188: * @param loader the context class loader
189: */
190: public static void addChildLoaderListener(
191: AddLoaderListener listener, ClassLoader loader) {
192: for (; loader != null; loader = loader.getParent()) {
193: if (loader instanceof EnvironmentClassLoader) {
194: ((EnvironmentClassLoader) loader)
195: .addLoaderListener(listener);
196: return;
197: }
198: }
199: }
200:
201: /**
202: * Add listener.
203: *
204: * @param listener object to listen for environment create/destroy
205: */
206: public static void addClassLoaderListener(
207: ClassLoaderListener listener) {
208: ClassLoader loader = Thread.currentThread()
209: .getContextClassLoader();
210:
211: addClassLoaderListener(listener, loader);
212: }
213:
214: /**
215: * Add listener.
216: *
217: * @param listener object to listen for environment create/destroy
218: * @param loader the context class loader
219: */
220: public static void addClassLoaderListener(
221: ClassLoaderListener listener, ClassLoader loader) {
222: for (; loader != null; loader = loader.getParent()) {
223: if (loader instanceof EnvironmentClassLoader) {
224: ((EnvironmentClassLoader) loader).addListener(listener);
225: return;
226: }
227: }
228:
229: _globalLoaderListeners.add(listener);
230: }
231:
232: /**
233: * Add close listener.
234: *
235: * @param listener object to listen for environment create/destroy
236: * @param loader the context class loader
237: */
238: public static void addCloseListener(Object obj) {
239: addClassLoaderListener(new CloseListener(obj));
240: }
241:
242: /**
243: * Starts the current environment.
244: */
245: public static void init() {
246: init(Thread.currentThread().getContextClassLoader());
247: }
248:
249: /**
250: * Starts the current environment.
251: */
252: public static void init(ClassLoader loader) {
253: for (; loader != null; loader = loader.getParent()) {
254: if (loader instanceof EnvironmentClassLoader) {
255: ((EnvironmentClassLoader) loader).init();
256: return;
257: }
258: }
259:
260: for (int i = 0; i < _globalLoaderListeners.size(); i++) {
261: ClassLoaderListener listener = _globalLoaderListeners
262: .get(i);
263:
264: listener.classLoaderInit(null);
265: }
266: }
267:
268: /**
269: * Starts the current environment.
270: */
271: public static void start() throws StartLifecycleException {
272: start(Thread.currentThread().getContextClassLoader());
273: }
274:
275: /**
276: * Starts the current environment.
277: */
278: public static void start(ClassLoader loader)
279: throws StartLifecycleException {
280: for (; loader != null; loader = loader.getParent()) {
281: if (loader instanceof EnvironmentClassLoader) {
282: ((EnvironmentClassLoader) loader).start();
283: return;
284: }
285: }
286:
287: init(loader);
288:
289: for (int i = 0; i < _globalEnvironmentListeners.size(); i++) {
290: EnvironmentListener listener = _globalEnvironmentListeners
291: .get(i);
292:
293: listener.environmentStart(null);
294: }
295: }
296:
297: /**
298: * Starts the current environment.
299: */
300: public static void stop() {
301: stop(Thread.currentThread().getContextClassLoader());
302: }
303:
304: /**
305: * Starts the current environment.
306: */
307: public static void stop(ClassLoader loader) {
308: for (; loader != null; loader = loader.getParent()) {
309: if (loader instanceof EnvironmentClassLoader) {
310: ((EnvironmentClassLoader) loader).stop();
311: return;
312: }
313: }
314:
315: ArrayList<EnvironmentListener> listeners;
316: listeners = new ArrayList<EnvironmentListener>();
317: listeners.addAll(_globalEnvironmentListeners);
318: _globalEnvironmentListeners.clear();
319:
320: for (int i = 0; i < listeners.size(); i++) {
321: EnvironmentListener listener = listeners.get(i);
322:
323: listener.environmentStop(null);
324: }
325: }
326:
327: /**
328: * Adds a dependency to the current environment.
329: *
330: * @param depend the dependency to add
331: */
332: public static void addDependency(Dependency depend) {
333: ClassLoader loader = Thread.currentThread()
334: .getContextClassLoader();
335:
336: addDependency(depend, loader);
337: }
338:
339: /**
340: * Adds a dependency to the current environment.
341: *
342: * @param depend the dependency to add
343: * @param loader the context loader
344: */
345: public static void addDependency(Dependency depend,
346: ClassLoader loader) {
347: for (; loader != null; loader = loader.getParent()) {
348: if (loader instanceof EnvironmentClassLoader) {
349: ((EnvironmentClassLoader) loader).addDependency(depend);
350: return;
351: }
352: }
353: }
354:
355: /**
356: * Returns the topmost dynamic class loader.
357: */
358: public static DynamicClassLoader getDynamicClassLoader() {
359: Thread thread = Thread.currentThread();
360:
361: return getDynamicClassLoader(thread.getContextClassLoader());
362: }
363:
364: /**
365: * Returns the topmost dynamic class loader.
366: *
367: * @param loader the context loader
368: */
369: public static DynamicClassLoader getDynamicClassLoader(
370: ClassLoader loader) {
371: for (; loader != null; loader = loader.getParent()) {
372: if (loader instanceof DynamicClassLoader) {
373: return (DynamicClassLoader) loader;
374: }
375: }
376:
377: return null;
378: }
379:
380: /**
381: * Adds a dependency to the current environment.
382: *
383: * @param depend the dependency to add
384: */
385: public static void addDependency(Path path) {
386: addDependency(new Depend(path));
387: }
388:
389: /**
390: * Adds a dependency to the current environment.
391: *
392: * @param path the dependency to add
393: * @param loader the context loader
394: */
395: public static void addDependency(Path path, ClassLoader loader) {
396: addDependency(new Depend(path), loader);
397: }
398:
399: /**
400: * Gets a local variable for the current environment.
401: *
402: * @param name the attribute name
403: *
404: * @return the attribute value
405: */
406: public static Object getAttribute(String name) {
407: ClassLoader loader = Thread.currentThread()
408: .getContextClassLoader();
409:
410: return getAttribute(name, loader);
411: }
412:
413: /**
414: * Returns the current dependency check interval.
415: */
416: public static long getDependencyCheckInterval() {
417: ClassLoader loader = Thread.currentThread()
418: .getContextClassLoader();
419:
420: for (; loader != null; loader = loader.getParent()) {
421: if (loader instanceof DynamicClassLoader)
422: return ((DynamicClassLoader) loader)
423: .getDependencyCheckInterval();
424: }
425:
426: return DynamicClassLoader.getGlobalDependencyCheckInterval();
427: }
428:
429: /**
430: * Returns the current dependency check interval.
431: */
432: public static long getDependencyCheckInterval(ClassLoader loader) {
433: for (; loader != null; loader = loader.getParent()) {
434: if (loader instanceof DynamicClassLoader)
435: return ((DynamicClassLoader) loader)
436: .getDependencyCheckInterval();
437: }
438:
439: return DynamicClassLoader.getGlobalDependencyCheckInterval();
440: }
441:
442: /**
443: * Gets a local variable for the current environment.
444: *
445: * @param name the attribute name
446: * @param loader the context loader
447: *
448: * @return the attribute value
449: */
450: public static Object getAttribute(String name, ClassLoader loader) {
451: for (; loader != null; loader = loader.getParent()) {
452: if (loader instanceof EnvironmentClassLoader) {
453: Object value = ((EnvironmentClassLoader) loader)
454: .getAttribute(name);
455:
456: if (value != null)
457: return value;
458: }
459: }
460:
461: return null;
462: }
463:
464: /**
465: * Gets a local variable for the current environment.
466: *
467: * @param name the attribute name
468: *
469: * @return the attribute value
470: */
471: public static Object getLevelAttribute(String name) {
472: ClassLoader loader = Thread.currentThread()
473: .getContextClassLoader();
474:
475: return getLevelAttribute(name, loader);
476: }
477:
478: /**
479: * Gets a local variable for the current environment.
480: *
481: * @param name the attribute name
482: * @param loader the context loader
483: *
484: * @return the attribute value
485: */
486: public static Object getLevelAttribute(String name,
487: ClassLoader loader) {
488: for (; loader != null; loader = loader.getParent()) {
489: if (loader instanceof EnvironmentClassLoader) {
490: return ((EnvironmentClassLoader) loader)
491: .getAttribute(name);
492: }
493: }
494:
495: return null;
496: }
497:
498: /**
499: * Sets a local variable for the current environment.
500: *
501: * @param name the attribute name
502: * @param value the new attribute value
503: *
504: * @return the old attribute value
505: */
506: public static Object setAttribute(String name, Object value) {
507: ClassLoader loader = Thread.currentThread()
508: .getContextClassLoader();
509:
510: return setAttribute(name, value, loader);
511: }
512:
513: /**
514: * Sets a local variable for the current environment.
515: *
516: * @param name the attribute name
517: * @param value the new attribute value
518: * @param loader the context loader
519: *
520: * @return the old attribute value
521: */
522: public static Object setAttribute(String name, Object value,
523: ClassLoader loader) {
524: for (; loader != null; loader = loader.getParent()) {
525: if (loader instanceof EnvironmentClassLoader) {
526: EnvironmentClassLoader envLoader = (EnvironmentClassLoader) loader;
527:
528: Object oldValue = envLoader.getAttribute(name);
529:
530: envLoader.setAttribute(name, value);
531:
532: if (oldValue != null)
533: return oldValue;
534: }
535: }
536:
537: return null;
538: }
539:
540: /**
541: * Adds a permission to the current environment.
542: *
543: * @param perm the permission to add.
544: *
545: * @return the old attribute value
546: */
547: public static void addPermission(Permission perm) {
548: ClassLoader loader = Thread.currentThread()
549: .getContextClassLoader();
550:
551: addPermission(perm, loader);
552: }
553:
554: /**
555: * Adds a permission to the current environment.
556: *
557: * @param perm the permission to add.
558: *
559: * @return the old attribute value
560: */
561: public static void addPermission(Permission perm, ClassLoader loader) {
562: for (; loader != null; loader = loader.getParent()) {
563: if (loader instanceof EnvironmentClassLoader) {
564: EnvironmentClassLoader envLoader = (EnvironmentClassLoader) loader;
565:
566: envLoader.addPermission(perm);
567: }
568: }
569: }
570:
571: /**
572: * Gets the class loader owner.
573: */
574: public static Object getOwner() {
575: ClassLoader loader = Thread.currentThread()
576: .getContextClassLoader();
577:
578: return getOwner(loader);
579: }
580:
581: /**
582: * Gets the class loader owner.
583: */
584: public static Object getOwner(ClassLoader loader) {
585: for (; loader != null; loader = loader.getParent()) {
586: if (loader instanceof EnvironmentClassLoader) {
587: EnvironmentClassLoader envLoader = (EnvironmentClassLoader) loader;
588:
589: Object owner = envLoader.getOwner();
590:
591: if (owner != null)
592: return owner;
593: }
594: }
595:
596: return null;
597: }
598:
599: /**
600: * Sets a configuration exception.
601: */
602: public static void setConfigException(Throwable e) {
603: ClassLoader loader = Thread.currentThread()
604: .getContextClassLoader();
605:
606: for (; loader != null; loader = loader.getParent()) {
607: if (loader instanceof EnvironmentClassLoader) {
608: EnvironmentClassLoader envLoader = (EnvironmentClassLoader) loader;
609:
610: envLoader.setConfigException(e);
611:
612: return;
613: }
614: }
615: }
616:
617: /**
618: * Returns any configuration exception.
619: */
620: public static Throwable getConfigException() {
621: ClassLoader loader = Thread.currentThread()
622: .getContextClassLoader();
623:
624: for (; loader != null; loader = loader.getParent()) {
625: if (loader instanceof EnvironmentClassLoader) {
626: EnvironmentClassLoader envLoader = (EnvironmentClassLoader) loader;
627:
628: if (envLoader.getConfigException() != null)
629: return envLoader.getConfigException();
630: }
631: }
632:
633: return null;
634: }
635:
636: /**
637: * Returns the environment name.
638: */
639: public static String getEnvironmentName() {
640: ClassLoader loader = Thread.currentThread()
641: .getContextClassLoader();
642:
643: for (; loader != null; loader = loader.getParent()) {
644: if (loader instanceof EnvironmentClassLoader) {
645: String name = ((EnvironmentClassLoader) loader).getId();
646:
647: if (name != null)
648: return name;
649: else
650: return "";
651: }
652: }
653:
654: return Thread.currentThread().getContextClassLoader()
655: .toString();
656: }
657:
658: /**
659: * Returns the classpath for the environment level.
660: */
661: public static String getLocalClassPath() {
662: ClassLoader loader = Thread.currentThread()
663: .getContextClassLoader();
664:
665: return getLocalClassPath(loader);
666: }
667:
668: /**
669: * Returns the classpath for the environment level.
670: */
671: public static String getLocalClassPath(ClassLoader loader) {
672: for (; loader != null; loader = loader.getParent()) {
673: if (loader instanceof EnvironmentClassLoader) {
674: return ((EnvironmentClassLoader) loader)
675: .getLocalClassPath();
676: }
677: }
678:
679: return CauchoSystem.getClassPath();
680: }
681:
682: /**
683: * destroys the current environment.
684: */
685: public static void closeGlobal() {
686: ArrayList<ClassLoaderListener> listeners;
687: listeners = new ArrayList<ClassLoaderListener>();
688: listeners.addAll(_globalLoaderListeners);
689: _globalLoaderListeners.clear();
690:
691: for (int i = 0; i < listeners.size(); i++) {
692: ClassLoaderListener listener = listeners.get(i);
693:
694: listener.classLoaderDestroy(null);
695: }
696: }
697: }
|