001: // ***************************************************************
002: // * *
003: // * File:ServiceContainerImpl.java *
004: // * *
005: // * Copyright (c) 2002 Sun Microsystems, Inc. *
006: // * All rights reserved. *
007: // * *
008: // * *
009: // * Date - Jul/16/2002 *
010: // * Author - alejandro.abdelnur@sun.com *
011: // * *
012: // ***************************************************************
013: package com.sun.portal.common.service.impl;
014:
015: import com.sun.portal.common.service.Service;
016: import com.sun.portal.common.service.ServiceContext;
017: import com.sun.portal.common.service.ServiceContainer;
018: import com.sun.portal.common.service.ServiceException;
019:
020: import java.util.List;
021: import java.util.ArrayList;
022: import java.util.Map;
023: import java.util.HashMap;
024: import java.io.File;
025: import java.io.InputStream;
026: import java.util.logging.Logger;
027:
028: import org.jdom.Document;
029: import org.jdom.Element;
030: import org.jdom.JDOMException;
031: import org.jdom.input.SAXBuilder;
032:
033: import com.sun.portal.log.common.PortalLogger;
034:
035: /**
036: * This is the default container implementation.
037: * <P>
038: * This ServiceContainer implementation has a DEFAULT_CONTEXT only.
039: * This context initializes all the services described in the service.xml
040: * file that has to be available in the root of the classpath.
041: * <P>
042: * Services are initialized in the order defined in in the service.xml
043: * and the destroy in reverse order.
044: * <P>
045: * The service.xml files must conform to the following 'schema'
046: * <P>
047: * <PRE>
048: * <services>
049: *
050: * <init-param> <!-- * -->
051: * <param-name> </param-name> <!-- 1 -->
052: * <param-value> </param-value> <!-- 1 -->
053: * </init-param>
054: *
055: * <service> <!-- * -->
056: * <service-name> </service-name> <!-- 1 -->
057: * <service-class> </service-class> <!-- 1 -->
058: * <init-timeout> </init-timeout> <!-- ? -->
059: * <destroy-timeout> </destroy-timeout> <!-- ? -->
060: * <init-param> <!-- * -->
061: * <param-name> </param-name> <!-- 1 -->
062: * <param-value> </param-value> <!-- 1 -->
063: * </init-param>
064: * </service>
065: *
066: * </services>
067: * </PRE>
068: * <P>
069: *
070: * @author <A HREF="mailto:tucu@sun.com">Alejandro Abdelnur</A>
071: *
072: */
073: public class ServiceContainerImpl extends ServiceContainer {
074: public static final int EXCO_OFFSET = 0;
075: public static final int EXCO_SERVICE_CONTEXT_FACTORY_INIT = EXCO_OFFSET + 0;
076:
077: private static final String SERVICES_DD_FILE = "services.xml";
078:
079: private static final String SERVICES_E = "services";
080: private static final String SERVICES_INIT_PARAM_E = "init-param";
081: private static final String SERVICES_INIT_PARAM_NAME_E = "param-name";
082: private static final String SERVICES_INIT_PARAM_VALUE_E = "param-value";
083: private static final String LOGGER_SERVICE_E = "logger-service";
084: private static final String SERVICE_E = "service";
085: private static final String SERVICE_NAME_E = "service-name";
086: private static final String SERVICE_CLASS_E = "service-class";
087: private static final String SERVICE_INIT_TIME_OUT_E = "init-timeout";
088: private static final String SERVICE_DESTROY_TIME_OUT_E = "destroy-timeout";
089: private static final String SERVICE_INIT_PARAM_E = "init-param";
090: private static final String SERVICE_INIT_PARAM_NAME_E = "param-name";
091: private static final String SERVICE_INIT_PARAM_VALUE_E = "param-value";
092:
093: private ServiceContextImpl _context;
094: private static Logger logger = PortalLogger
095: .getLogger(ServiceContainerImpl.class);
096:
097: /**
098: * Initializes the ServiceContainer object.
099: * <P>
100: * This method must be called before any ServiceContext
101: * can be retrieved from the container.
102: * <P>
103: * The init method must complete successfully in order
104: * for the container to be operational.
105: * <P>
106: * This method parses the service.xml file and initializes
107: * all the services defined in it.
108: * <P>
109: *
110: * @throws ServiceException if an exception has occurred
111: * that interferes with the container's normal
112: * initialization
113: *
114: */
115: public void init() throws ServiceException {
116: Map initParams = new HashMap();
117: ServiceContextImpl.ServiceData[] serviceData = null;
118:
119: try {
120: InputStream is = getClass().getClassLoader()
121: .getResourceAsStream(SERVICES_DD_FILE);
122: SAXBuilder builder = new SAXBuilder();
123: Document doc = builder.build(is);
124: is.close();
125: Element servicesE = doc.getRootElement();
126: List servicesInitParamsE = servicesE
127: .getChildren(SERVICES_INIT_PARAM_E);
128: for (int i = 0; i < servicesInitParamsE.size(); i++) {
129: Element initParam = (Element) servicesInitParamsE
130: .get(i);
131: String name = initParam.getChild(
132: SERVICES_INIT_PARAM_NAME_E).getTextTrim();
133: String value = initParam.getChild(
134: SERVICES_INIT_PARAM_VALUE_E).getTextTrim();
135: initParams.put(name, value);
136: }
137: List services = new ArrayList();
138: Element loggerE = servicesE.getChild(LOGGER_SERVICE_E);
139: services.add(parseService(loggerE, DEFAULT_CONTEXT
140: + "CtxLog"));
141:
142: List serviceListE = servicesE.getChildren(SERVICE_E);
143: for (int i = 0; i < serviceListE.size(); i++) {
144: Element serviceE = (Element) serviceListE.get(i);
145: services.add(parseService(serviceE, null));
146: }
147: serviceData = new ServiceContextImpl.ServiceData[services
148: .size()];
149: services.toArray(serviceData);
150: } catch (Exception ex) {
151: throw new ServiceException(
152: EXCO_SERVICE_CONTEXT_FACTORY_INIT, "reading SDD",
153: ex);
154: }
155:
156: _context = new ServiceContextImpl(DEFAULT_CONTEXT, initParams,
157: serviceData);
158: _context.init();
159:
160: if (logger != null) {
161: logger.info("ServiceContainer, initialized");
162: }
163: }
164:
165: /**
166: * Parses a logger-service or a service entry and returns
167: * a ServiceData with all the info.
168: *
169: * @param forceName if not null uses this value instead of name in service definition
170: */
171: private ServiceContextImpl.ServiceData parseService(
172: Element serviceE, String forceName) {
173: String serviceName = (forceName != null) ? forceName : serviceE
174: .getChild(SERVICE_NAME_E).getTextTrim();
175: String serviceClassName = serviceE.getChild(SERVICE_CLASS_E)
176: .getTextTrim();
177: int initTimeout = -1;
178: Element initTimeoutE = serviceE
179: .getChild(SERVICE_INIT_TIME_OUT_E);
180: if (initTimeoutE != null) {
181: initTimeout = Integer.parseInt(initTimeoutE.getTextTrim());
182: }
183: int destroyTimeout = -1;
184: Element destroyTimeoutE = serviceE
185: .getChild(SERVICE_DESTROY_TIME_OUT_E);
186: if (destroyTimeoutE != null) {
187: destroyTimeout = Integer.parseInt(destroyTimeoutE
188: .getTextTrim());
189: }
190:
191: Map serviceInitParams = new HashMap();
192: List serviceInitParamsE = serviceE
193: .getChildren(SERVICE_INIT_PARAM_E);
194: for (int j = 0; j < serviceInitParamsE.size(); j++) {
195: Element initParam = (Element) serviceInitParamsE.get(j);
196: String name = initParam
197: .getChild(SERVICES_INIT_PARAM_NAME_E).getTextTrim();
198: String value = initParam.getChild(
199: SERVICES_INIT_PARAM_VALUE_E).getTextTrim();
200: serviceInitParams.put(name, value);
201: }
202: return new ServiceContextImpl.ServiceData(serviceName,
203: serviceClassName, serviceInitParams, initTimeout,
204: destroyTimeout);
205: }
206:
207: /**
208: * Returns the named ServiceContext of the container.
209: * <P>
210: * This container implementation only supports the default container.
211: * <P>
212: *
213: * @param name a String containing the name of the context
214: * to retrieve
215: *
216: * @return the ServiceContext with the given name, or null
217: * if the context does not exist
218: *
219: */
220: public ServiceContext getContext(String name) {
221: return (name.equals(DEFAULT_CONTEXT)) ? _context : null;
222: }
223:
224: /**
225: * Destroys the ServiceContainer object.
226: * <P>
227: * This method must be called to take the container out of
228: * service. After this method completes, the container
229: * is not active anymore.
230: * <P>
231: * It destroys the default context.
232: * <P>
233: *
234: */
235: public void destroy() {
236: if (logger != null) {
237: logger.info("ServiceContainer, destroying");
238: }
239: _context.destroy();
240: }
241:
242: }
|