001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.servicemix.common;
018
019 import java.util.ArrayList;
020 import java.util.Collection;
021 import java.util.LinkedHashMap;
022 import java.util.List;
023 import java.util.Map;
024
025 import javax.jbi.JBIException;
026 import javax.jbi.management.DeploymentException;
027 import javax.jbi.management.LifeCycleMBean;
028
029 public class DefaultServiceUnit implements ServiceUnit {
030
031 protected ServiceMixComponent component;
032
033 protected String name;
034
035 protected String rootPath;
036
037 protected String status = LifeCycleMBean.SHUTDOWN;
038
039 protected Map<String, Endpoint> endpoints = new LinkedHashMap<String, Endpoint>();
040
041 public DefaultServiceUnit() {
042 }
043
044 public DefaultServiceUnit(ServiceMixComponent component) {
045 this.component = component;
046 }
047
048 public synchronized void init() throws Exception {
049 if (this.status == LifeCycleMBean.SHUTDOWN) {
050 // Activate endpoints
051 List<Endpoint> activated = new ArrayList<Endpoint>();
052 try {
053 for (Endpoint endpoint : getEndpoints()) {
054 endpoint.activate();
055 activated.add(endpoint);
056 }
057 this.status = LifeCycleMBean.STOPPED;
058 } catch (Exception e) {
059 // Deactivate activated endpoints
060 for (Endpoint endpoint : activated) {
061 try {
062 endpoint.deactivate();
063 } catch (Exception e2) {
064 // do nothing
065 }
066 }
067 throw e;
068 }
069 }
070 }
071
072 public synchronized void start() throws Exception {
073 if (this.status == LifeCycleMBean.STOPPED) {
074 // Activate endpoints
075 List<Endpoint> activated = new ArrayList<Endpoint>();
076 try {
077 for (Endpoint endpoint : getEndpoints()) {
078 endpoint.start();
079 }
080 this.status = LifeCycleMBean.STARTED;
081 } catch (Exception e) {
082 // Deactivate activated endpoints
083 for (Endpoint endpoint : activated) {
084 try {
085 endpoint.stop();
086 } catch (Exception e2) {
087 // do nothing
088 }
089 }
090 throw e;
091 }
092 }
093 }
094
095 public synchronized void stop() throws Exception {
096 if (this.status == LifeCycleMBean.STARTED) {
097 this.status = LifeCycleMBean.STOPPED;
098 // Stop endpoints
099 Exception exception = null;
100 for (Endpoint endpoint : getEndpoints()) {
101 try {
102 endpoint.stop();
103 } catch (Exception e) {
104 exception = e;
105 }
106 }
107 if (exception != null) {
108 throw exception;
109 }
110 }
111 }
112
113 public synchronized void shutDown() throws Exception {
114 if (this.status == LifeCycleMBean.STARTED) {
115 stop();
116 }
117 if (this.status == LifeCycleMBean.STOPPED) {
118 this.status = LifeCycleMBean.SHUTDOWN;
119 // Deactivate endpoints
120 Exception exception = null;
121 for (Endpoint endpoint : getEndpoints()) {
122 try {
123 // TODO: uncomment when all tests in various components work fine
124 // TODO: we also need to find a way to not wait forever on this call
125 //component.prepareShutdown(endpoint);
126 endpoint.deactivate();
127 } catch (Exception e) {
128 exception = e;
129 }
130 }
131 if (exception != null) {
132 throw exception;
133 }
134 }
135 }
136
137 public String getCurrentState() {
138 return status;
139 }
140
141 public String getName() {
142 return name;
143 }
144
145 public void setName(String name) {
146 this.name = name;
147 }
148
149 public String getRootPath() {
150 return rootPath;
151 }
152
153 public void setRootPath(String rootPath) {
154 this.rootPath = rootPath;
155 }
156
157 /**
158 * @return Returns the component.
159 */
160 public ServiceMixComponent getComponent() {
161 return component;
162 }
163
164 /**
165 * @param component
166 * The component to set.
167 */
168 public void setComponent(ServiceMixComponent component) {
169 this.component = component;
170 }
171
172 public Collection<Endpoint> getEndpoints() {
173 return this.endpoints.values();
174 }
175
176 public synchronized void addEndpoint(Endpoint endpoint) throws DeploymentException {
177 String key = endpoint.getKey();
178 if (this.endpoints.put(key, endpoint) != null) {
179 throw new DeploymentException(
180 "More than one endpoint found in the SU for key: " + key);
181 }
182 if (this.status == LifeCycleMBean.STOPPED) {
183 try {
184 endpoint.activate();
185 } catch (Exception e) {
186 throw new DeploymentException(e);
187 }
188 } else if (this.status == LifeCycleMBean.STARTED) {
189 try {
190 endpoint.activate();
191 endpoint.start();
192 } catch (Exception e) {
193 throw new DeploymentException(e);
194 }
195 }
196 }
197
198 public synchronized void removeEndpoint(Endpoint endpoint) throws DeploymentException {
199 String key = endpoint.getKey();
200 if (this.endpoints.remove(key) == null) {
201 throw new DeploymentException("Endpoint not found in the SU for key: " + EndpointSupport.getKey(endpoint));
202 }
203 if (this.status == LifeCycleMBean.STOPPED) {
204 try {
205 component.prepareShutdown(endpoint);
206 endpoint.deactivate();
207 } catch (Exception e) {
208 throw new DeploymentException(e);
209 }
210 } else if (this.status == LifeCycleMBean.STARTED) {
211 try {
212 endpoint.stop();
213 component.prepareShutdown(endpoint);
214 endpoint.deactivate();
215 } catch (Exception e) {
216 throw new DeploymentException(e);
217 }
218 }
219 }
220
221 public Endpoint getEndpoint(String key) {
222 return this.endpoints.get(key);
223 }
224
225 public ClassLoader getConfigurationClassLoader() {
226 return component.getClass().getClassLoader();
227 }
228
229 }