001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019:
020: package org.apache.geronimo.openjpa;
021:
022: import java.net.URI;
023: import java.net.URISyntaxException;
024: import java.util.Collections;
025: import java.util.HashMap;
026:
027: import org.apache.commons.logging.Log;
028: import org.apache.commons.logging.LogFactory;
029: import org.apache.geronimo.gbean.AbstractName;
030: import org.apache.geronimo.gbean.AbstractNameQuery;
031: import org.apache.geronimo.gbean.GBeanLifecycle;
032: import org.apache.geronimo.gbean.GBeanInfo;
033: import org.apache.geronimo.gbean.GBeanInfoBuilder;
034: import org.apache.geronimo.kernel.Kernel;
035: import org.apache.geronimo.kernel.GBeanNotFoundException;
036: import org.apache.geronimo.kernel.config.Configuration;
037: import org.apache.geronimo.kernel.lifecycle.LifecycleListener;
038: import org.apache.geronimo.kernel.repository.Artifact;
039:
040: import org.apache.openjpa.enhance.PCRegistry;
041:
042: /**
043: * Monitor configuration lifecycle events. Whenever a configuration is stopped, inform OpenJPA that the ClassLoader is no longer needed.
044: *
045: * @version $Rev: 577720 $ $Date: 2007-09-20 05:40:04 -0700 (Thu, 20 Sep 2007) $
046: */
047: public class ConfigurationMonitorGBean implements GBeanLifecycle {
048: private static final Log log = LogFactory
049: .getLog(ConfigurationMonitorGBean.class);
050:
051: private final Kernel kernel;
052: private final LifecycleListener listener;
053: private HashMap<AbstractName, ClassLoader> classLoaderMap = new HashMap<AbstractName, ClassLoader>();
054:
055: public ConfigurationMonitorGBean(Kernel kernel) {
056: this .kernel = kernel;
057: this .listener = createLifecycleListener();
058: }
059:
060: /**
061: * Create a LifecycleListenr that will be informed of lifecycle events.
062: * We only care about running (the configuration ClassLoader cannot be retrieved when the Configuration is stopping)
063: * and stopped.
064: */
065: private LifecycleListener createLifecycleListener() {
066: return new LifecycleListener() {
067: public void loaded(AbstractName abstractName) {
068: }
069:
070: public void starting(AbstractName abstractName) {
071: }
072:
073: public void running(AbstractName abstractName) {
074: configurationRunning(abstractName);
075: }
076:
077: public void stopping(AbstractName abstractName) {
078: }
079:
080: public void stopped(AbstractName abstractName) {
081: configurationStopped(abstractName);
082: }
083:
084: public void failed(AbstractName abstractName) {
085: }
086:
087: public void unloaded(AbstractName abstractName) {
088: }
089:
090: };
091: }
092:
093: /**
094: * Cache the ClassLoader for a newly started Configuration.
095: */
096: private void configurationRunning(AbstractName name) {
097: try {
098: Configuration config = (Configuration) kernel
099: .getGBean(name);
100: classLoaderMap.put(name, config
101: .getConfigurationClassLoader());
102: } catch (GBeanNotFoundException gnfe) {
103: log.warn("Could not retrieve GBean for artifact: "
104: + name.toString(), gnfe);
105: }
106: }
107:
108: /**
109: * Notify OpenJPA that the ClassLoader will no longer be used. This allows OpenJPA to free up
110: * HARD references that would otherwise prevent Geronimo ClassLoaders from being GCed.
111: */
112: private void configurationStopped(AbstractName name) {
113: ClassLoader classLoader = classLoaderMap.remove(name);
114: if (classLoader == null) {
115: log.debug("Could not locate ClassLoader for artifact: "
116: + name.toString());
117: }
118: PCRegistry.deRegister(classLoader);
119: }
120:
121: /**
122: * This GBean is being started. Register our listener with the Lifecycle monitor.
123: */
124: public void doStart() {
125: AbstractNameQuery configurationQuery = new AbstractNameQuery(
126: Configuration.class.getName());
127: kernel.getLifecycleMonitor().addLifecycleListener(listener,
128: configurationQuery);
129: }
130:
131: /**
132: * This GBean is being stopped. Remove the LifecycleListener.
133: */
134: public void doStop() {
135: kernel.getLifecycleMonitor().removeLifecycleListener(listener);
136: }
137:
138: public void doFail() {
139: doStop();
140: }
141:
142: public static final GBeanInfo GBEAN_INFO;
143:
144: static {
145: GBeanInfoBuilder infoBuilder = GBeanInfoBuilder
146: .createStatic(ConfigurationMonitorGBean.class);
147: infoBuilder.addAttribute("kernel", Kernel.class, false);
148: infoBuilder.setConstructor(new String[] { "kernel", });
149: GBEAN_INFO = infoBuilder.getBeanInfo();
150: }
151:
152: public static GBeanInfo getGBeanInfo() {
153: return GBEAN_INFO;
154: }
155: }
|