1 /**
2 *
3 * Copyright 2004 The Apache Software Foundation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.geronimo.gbean.runtime;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.apache.geronimo.gbean.AbstractName;
22 import org.apache.geronimo.gbean.AbstractNameQuery;
23 import org.apache.geronimo.gbean.InvalidConfigurationException;
24 import org.apache.geronimo.kernel.GBeanNotFoundException;
25 import org.apache.geronimo.kernel.Kernel;
26 import org.apache.geronimo.kernel.lifecycle.LifecycleAdapter;
27 import org.apache.geronimo.kernel.lifecycle.LifecycleListener;
28 import org.apache.geronimo.kernel.management.State;
29
30 /**
31 * @version $Rev: 430508 $ $Date: 2006-08-10 12:56:47 -0700 (Thu, 10 Aug 2006) $
32 */
33 public final class GBeanDependency {
34
35
36 private static final Log log = LogFactory.getLog(GBeanDependency.class);
37
38 /**
39 * The GBeanInstance to which this reference belongs.
40 */
41 private final GBeanInstance gbeanInstance;
42
43 /**
44 * The target objectName targetName to watch for a connection.
45 */
46 private final AbstractName targetName;
47
48 /**
49 * Our listener for lifecycle events
50 */
51 private final LifecycleListener listener;
52
53 /**
54 * The kernel to which the reference is bound.
55 */
56 private final Kernel kernel;
57
58 private boolean targetRunning = false;
59 private boolean dependencyRegistered = false;
60
61 public GBeanDependency(GBeanInstance gbeanInstance, AbstractName targetName, Kernel kernel) throws InvalidConfigurationException {
62 this.gbeanInstance = gbeanInstance;
63 this.kernel = kernel;
64 this.targetName = targetName;
65 listener = createLifecycleListener();
66 }
67
68 public AbstractName getTargetName() {
69 return targetName;
70 }
71
72 public final synchronized void online() {
73
74 AbstractNameQuery query = new AbstractNameQuery(targetName, null);
75 kernel.getLifecycleMonitor().addLifecycleListener(listener, query);
76 targetRunning = isRunning(kernel, targetName);
77 }
78
79 public synchronized boolean start() {
80 if (targetRunning && !dependencyRegistered) {
81 AbstractName abstractName = gbeanInstance.getAbstractName();
82 kernel.getDependencyManager().addDependency(abstractName, targetName);
83 dependencyRegistered = true;
84 }
85 return targetRunning;
86 }
87
88
89 public synchronized void stop() {
90 if (dependencyRegistered) {
91 AbstractName abstractName = gbeanInstance.getAbstractName();
92 kernel.getDependencyManager().removeDependency(abstractName, targetName);
93 dependencyRegistered = false;
94 }
95 }
96
97 public final synchronized void offline() {
98
99 stop();
100
101 kernel.getLifecycleMonitor().removeLifecycleListener(listener);
102 targetRunning = false;
103 }
104
105 private synchronized void attemptFullStart() {
106 try {
107
108
109
110
111 gbeanInstance.start();
112 } catch (Exception e) {
113 log.warn("Exception occured while attempting to fully start: objectName=" + gbeanInstance.getObjectName(), e);
114 }
115 }
116
117 protected LifecycleListener createLifecycleListener() {
118 return new LifecycleAdapter() {
119 public void running(AbstractName abstractName) {
120 addTarget(abstractName);
121 }
122
123 public void stopped(AbstractName abstractName) {
124 removeTarget(abstractName);
125 }
126
127 public void failed(AbstractName abstractName) {
128 removeTarget(abstractName);
129 }
130
131 public void unloaded(AbstractName abstractName) {
132 removeTarget(abstractName);
133 }
134 };
135 }
136
137 protected final void addTarget(AbstractName abstractName) {
138
139 synchronized (this) {
140 targetRunning = true;
141 GBeanInstance gbeanInstance1 = gbeanInstance;
142 if (gbeanInstance1.getStateInstance() == State.RUNNING) {
143 log.error("Illegal state: two or more targets are running for a dependency: " + getDescription() +
144 ",\n newTarget=" + abstractName);
145 }
146 attemptFullStart();
147 }
148 }
149
150 protected final void removeTarget(AbstractName abstractName) {
151 synchronized (this) {
152 targetRunning = false;
153 GBeanInstance gbeanInstance1 = gbeanInstance;
154 if (gbeanInstance1.getStateInstance() == State.RUNNING) {
155
156 log.error("Illegal state: current target for a single valued reference stopped: " + getDescription() +
157 ",\n stopped Target=" + abstractName);
158 gbeanInstance1.referenceFailed();
159 }
160 }
161 }
162
163
164 /**
165 * Is the component in the Running state
166 *
167 * @param objectName name of the component to check
168 * @return true if the component is running; false otherwise
169 */
170 private boolean isRunning(Kernel kernel, AbstractName objectName) {
171 try {
172 final int state = kernel.getGBeanState(objectName);
173 return state == State.RUNNING_INDEX;
174 } catch (GBeanNotFoundException e) {
175
176 return false;
177 } catch (Exception e) {
178
179 return false;
180 }
181 }
182
183 protected final String getDescription() {
184 return "\n GBeanInstance: " + gbeanInstance.getName() +
185 "\n Target Name: " + targetName;
186 }
187
188 public boolean equals(Object o) {
189 if (this == o) return true;
190 if (o == null || getClass() != o.getClass()) return false;
191
192 final GBeanDependency that = (GBeanDependency) o;
193
194 if (gbeanInstance != null ? !gbeanInstance.equals(that.gbeanInstance) : that.gbeanInstance != null) {
195 return false;
196 }
197 return !(targetName != null ? !targetName.equals(that.targetName) : that.targetName != null);
198
199 }
200
201 public int hashCode() {
202 int result;
203 result = (gbeanInstance != null ? gbeanInstance.hashCode() : 0);
204 result = 29 * result + (targetName != null ? targetName.hashCode() : 0);
205 return result;
206 }
207 }