View Javadoc

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          //TODO consider including interfaces in query
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          // make sure we are stopped
99          stop();
100 
101         kernel.getLifecycleMonitor().removeLifecycleListener(listener);
102         targetRunning = false;
103     }
104 
105     private synchronized void attemptFullStart() {
106         try {
107             // there could be an issue with really badly written components holding up a stop when the
108             // component never reached the starting phase... then a target registers and we automatically
109             // attempt to restart
110 //            waitingForMe = false;
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         // if we are running, and we now have two valid targets, which is an illegal state so we need to fail
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                 // we no longer have a valid target, which is an illegal state so we need to fail
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             // gbean is no longer registerd
176             return false;
177         } catch (Exception e) {
178             // problem getting the attribute, gbean has most likely failed
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 }