001: /*
002: * (C) Copyright 2000 - 2005 Nabh Information Systems, Inc.
003: *
004: * This program is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU General Public License
006: * as published by the Free Software Foundation; either version 2
007: * of the License, or (at your option) any later version.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: *
018: */
019: package com.nabhinc.ws.server;
020:
021: import java.io.IOException;
022: import java.io.Writer;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Vector;
026:
027: import org.apache.commons.logging.LogFactory;
028: import org.apache.commons.logging.Log;
029:
030: import org.w3c.dom.Element;
031:
032: import com.nabhinc.util.XMLUtil;
033: import com.nabhinc.ws.core.WebServiceException;
034:
035: /**
036: * Provides static methods to manage life-cycle of Web services.
037: *
038: * @author Padmanabh Dabke
039: * (c) 2005 Nabh Information Systems, Inc. All Rights Reserved.
040: */
041: public class WebServiceManager {
042: private static Log wsmLogger = LogFactory
043: .getLog(WebServiceManager.class);
044:
045: private static WebServiceDirectory wsmServiceDirectory = null;
046:
047: // Server context that provides server URLs, server ID, etc.
048: private static WebServiceContext wsmServerContext = null;
049: private static RequestProcessor wsmRequestProcessor = null;
050: private static Vector wsmClassMappingList = new Vector();
051:
052: private static Vector wsmLifeCycleListeners = new Vector();
053:
054: protected static void init(Element root,
055: WebServiceDirectory serviceDir,
056: WebServiceContext serviceContext,
057: RequestProcessor reqProcessor) throws WebServiceException {
058: wsmServiceDirectory = serviceDir;
059: wsmServerContext = serviceContext;
060: wsmRequestProcessor = reqProcessor;
061:
062: populateClassPropertyMapping(root);
063:
064: Element wsRootElem = XMLUtil.getSubElement(root,
065: WebServiceServerConstants.WEB_SERVICES_TAG);
066: if (wsRootElem == null) {
067: WebServiceServlet.getInstance().warn(
068: "Web services configuration not found.");
069: return;
070: }
071:
072: Element[] wsElems = XMLUtil.getSubElements(wsRootElem,
073: WebServiceServerConstants.WEB_SERVICE_TAG);
074: if (wsElems == null || wsElems.length == 0) {
075: WebServiceServlet
076: .getInstance()
077: .warn(
078: "Web services configuration does not define any services.");
079: } else {
080: for (int i = 0; i < wsElems.length; i++) {
081: WebServiceInfo wsInfo = new WebServiceInfo();
082: wsInfo.init(wsElems[i], wsmServerContext,
083: wsmRequestProcessor);
084: try {
085: _addWebService(wsInfo);
086: } catch (WebServiceException ex) {
087: if (wsInfo.isCritical)
088: throw ex;
089: wsmLogger.error(
090: "Failed to load non-critical service "
091: + wsInfo.name, ex);
092: }
093: }
094: }
095:
096: }
097:
098: protected static void serialize(String indent, String delta,
099: Writer w) throws IOException, WebServiceException {
100: serializeClassPropertyMapping(indent, delta, w);
101: XMLUtil.writeElementStart(indent,
102: WebServiceServerConstants.WEB_SERVICES_TAG, w);
103: List serviceList = wsmServiceDirectory.getWebServiceInfoList();
104: String indent1 = indent + delta;
105: for (int i = 0; i < serviceList.size(); i++) {
106: WebServiceInfo wsInfo = (WebServiceInfo) serviceList.get(i);
107: wsInfo.serialize(indent1, delta, w);
108: }
109: XMLUtil.writeElementEnd(indent,
110: WebServiceServerConstants.WEB_SERVICES_TAG, w);
111: }
112:
113: public static List getWebServiceInfoList()
114: throws WebServiceException {
115: return wsmServiceDirectory.getWebServiceInfoList();
116: }
117:
118: public static WebServiceInfo getWebServiceInfo(String name)
119: throws WebServiceException {
120: return wsmServiceDirectory.lookup(name);
121: }
122:
123: public static void loadWebService(String name)
124: throws WebServiceException {
125: WebServiceInfo wsInfo = getWebServiceInfo(name);
126: if (wsInfo == null)
127: throw new WebServiceException("No such service: " + name
128: + ".");
129: wsInfo.load();
130: notifyWebServiceLifeCycleListeners(name,
131: WebServiceLifeCycleEvent.WSLCE_LOADED);
132: }
133:
134: public static void unloadWebService(String name)
135: throws WebServiceException {
136: WebServiceInfo wsInfo = getWebServiceInfo(name);
137: if (wsInfo == null)
138: throw new WebServiceException("No such service: " + name
139: + ".");
140: wsInfo.unload();
141: notifyWebServiceLifeCycleListeners(name,
142: WebServiceLifeCycleEvent.WSLCE_UNLOADED);
143: }
144:
145: public static void reloadWebService(String name)
146: throws WebServiceException {
147: WebServiceInfo wsInfo = getWebServiceInfo(name);
148: if (wsInfo == null)
149: throw new WebServiceException("No such service: " + name
150: + ".");
151: wsInfo.reload();
152: notifyWebServiceLifeCycleListeners(name,
153: WebServiceLifeCycleEvent.WSLCE_RELOADED);
154: }
155:
156: public static void deleteWebService(String name)
157: throws WebServiceException, IOException {
158: WebServiceInfo wsInfo = wsmServiceDirectory.lookup(name);
159: if (wsInfo != null) {
160: wsInfo.unload();
161: wsmServiceDirectory.unregister(name);
162: WebServiceServlet.getInstance().save();
163: }
164: notifyWebServiceLifeCycleListeners(name,
165: WebServiceLifeCycleEvent.WSLCE_DELETED);
166: }
167:
168: private static void _addWebService(WebServiceInfo wsInfo)
169: throws WebServiceException {
170:
171: wsmServiceDirectory.register(wsInfo);
172: wsmLogger.info("Registered Web service " + wsInfo.name);
173: if (!wsInfo.manualLoad) {
174: wsInfo.load();
175: wsmLogger.info("Started Web service " + wsInfo.name);
176: }
177: }
178:
179: public static void addWebService(WebServiceInfo wsInfo)
180: throws WebServiceException, IOException {
181: wsInfo.init(wsmServerContext, wsmRequestProcessor);
182: _addWebService(wsInfo);
183: WebServiceServlet.getInstance().save();
184: }
185:
186: public static void startWebService(String name)
187: throws WebServiceException {
188: WebServiceInfo wsInfo = getWebServiceInfo(name);
189: if (wsInfo == null)
190: throw new WebServiceException("No such service: " + name
191: + ".");
192: wsInfo.start();
193: notifyWebServiceLifeCycleListeners(name,
194: WebServiceLifeCycleEvent.WSLCE_STARTED);
195: }
196:
197: public static void stopWebService(String name)
198: throws WebServiceException {
199: WebServiceInfo wsInfo = getWebServiceInfo(name);
200: if (wsInfo == null)
201: throw new WebServiceException("No such service: " + name
202: + ".");
203: wsInfo.stop();
204: notifyWebServiceLifeCycleListeners(name,
205: WebServiceLifeCycleEvent.WSLCE_STOPPED);
206: }
207:
208: protected static String getServiceImplClassProperty(
209: String adapterClassName) throws ClassNotFoundException {
210: Class adapterClass = Class.forName(adapterClassName);
211: for (int i = 0; i < wsmClassMappingList.size(); i++) {
212: String[] classPropertyMapping = (String[]) wsmClassMappingList
213: .elementAt(i);
214: Class cl = Class.forName(classPropertyMapping[0]);
215: if (cl.isAssignableFrom(adapterClass))
216: return classPropertyMapping[1];
217: }
218: return null;
219: }
220:
221: private static void populateClassPropertyMapping(Element root)
222: throws WebServiceException {
223: Element mappingRoot = XMLUtil
224: .getSubElement(
225: root,
226: WebServiceServerConstants.SERVICE_INTERFACE_PROPERTY_NAME_MAPPINGS);
227: if (mappingRoot == null)
228: return;
229:
230: Element[] mappingElems = XMLUtil
231: .getSubElements(
232: mappingRoot,
233: WebServiceServerConstants.SERVICE_INTERFACE_PROPERTY_NAME_MAPPING);
234:
235: if (mappingElems == null || mappingElems.length == 0)
236: return;
237:
238: for (int i = 0; i < mappingElems.length; i++) {
239: String implClass = XMLUtil.getSubElementText(
240: mappingElems[i],
241: WebServiceServerConstants.CLASS_TAG);
242: if (implClass == null)
243: throw new WebServiceException(
244: "Missing service impl class name in class-property name mapping.");
245: String propName = XMLUtil.getSubElementText(
246: mappingElems[i],
247: WebServiceServerConstants.PROPERTY_NAME_TAG);
248: if (propName == null)
249: throw new WebServiceException(
250: "Missing service property name in class-property name mapping.");
251: String[] mapping = new String[2];
252: mapping[0] = implClass;
253: mapping[1] = propName;
254: wsmClassMappingList.addElement(mapping);
255: }
256: }
257:
258: private static void serializeClassPropertyMapping(String indent,
259: String delta, Writer w) throws IOException {
260: if (wsmClassMappingList.size() == 0)
261: return;
262: XMLUtil
263: .writeElementStart(
264: indent,
265: WebServiceServerConstants.SERVICE_INTERFACE_PROPERTY_NAME_MAPPINGS,
266: w);
267: String indent1 = indent + delta;
268: String indent2 = indent1 + delta;
269: for (int i = 0; i < wsmClassMappingList.size(); i++) {
270: String[] mapping = (String[]) wsmClassMappingList
271: .elementAt(i);
272: XMLUtil
273: .writeElementStart(
274: indent1,
275: WebServiceServerConstants.SERVICE_INTERFACE_PROPERTY_NAME_MAPPING,
276: w);
277: XMLUtil.writeElement(indent2,
278: WebServiceServerConstants.CLASS_TAG, mapping[0], w);
279: XMLUtil.writeElement(indent2,
280: WebServiceServerConstants.PROPERTY_NAME_TAG,
281: mapping[1], w);
282:
283: XMLUtil
284: .writeElementEnd(
285: indent1,
286: WebServiceServerConstants.SERVICE_INTERFACE_PROPERTY_NAME_MAPPING,
287: w);
288:
289: }
290: XMLUtil
291: .writeElementEnd(
292: indent,
293: WebServiceServerConstants.SERVICE_INTERFACE_PROPERTY_NAME_MAPPINGS,
294: w);
295:
296: }
297:
298: private static void notifyWebServiceLifeCycleListeners(
299: String wsName, int eventType) {
300: WebServiceLifeCycleEvent e = new WebServiceLifeCycleEvent();
301: e.type = eventType;
302: e.webServiceName = wsName;
303: for (int i = 0; i < wsmLifeCycleListeners.size(); i++) {
304: WebServiceLifeCycleListener listener = (WebServiceLifeCycleListener) wsmLifeCycleListeners
305: .get(i);
306: listener.processEvent(e);
307: }
308: }
309:
310: @SuppressWarnings("unchecked")
311: public static void addWebServiceLifeCycleListener(
312: WebServiceLifeCycleListener l) {
313: if (!wsmLifeCycleListeners.contains(l))
314: wsmLifeCycleListeners.addElement(l);
315: }
316:
317: public static void removeWebServiceLifeCycleListener(
318: WebServiceLifeCycleListener l) {
319: wsmLifeCycleListeners.remove(l);
320: }
321:
322: protected static void destroy() {
323: try {
324: List wsList = wsmServiceDirectory.getWebServiceInfoList();
325:
326: for (Iterator iter = wsList.iterator(); iter.hasNext();) {
327: WebServiceInfo wsInfo = (WebServiceInfo) iter.next();
328: wsInfo.unload();
329: notifyWebServiceLifeCycleListeners(wsInfo.name,
330: WebServiceLifeCycleEvent.WSLCE_UNLOADED);
331: }
332: } catch (Exception e) {
333: // Ignore
334: }
335: }
336:
337: }
|