001: /*
002: * Copyright 2004-2005 Sun Microsystems, Inc. All
003: * rights reserved. Use of this product is subject
004: * to license terms. Federal Acquisitions:
005: * Commercial Software -- Government Users
006: * Subject to Standard License Terms and
007: * Conditions.
008: *
009: * Sun, Sun Microsystems, the Sun logo, and Sun ONE
010: * are trademarks or registered trademarks of Sun Microsystems,
011: * Inc. in the United States and other countries.
012: */
013: package com.sun.portal.portletappengine.impl;
014:
015: import com.sun.portal.log.common.PortalLogger;
016: import com.sun.portal.portlet.impl.PortalContextImpl;
017: import com.sun.portal.portlet.impl.PortletConfigImpl;
018: import com.sun.portal.portlet.impl.PortletContextImpl;
019: import com.sun.portal.portletappengine.LifecycleManager;
020: import com.sun.portal.portletcontainercommon.descriptor.DeploymentDescriptorException;
021: import com.sun.portal.portletcontainercommon.descriptor.DeploymentDescriptorReader;
022: import com.sun.portal.portletcontainercommon.descriptor.PortletAppDescriptor;
023: import com.sun.portal.portletcontainercommon.descriptor.PortletDescriptor;
024: import com.sun.portal.portletcontainercommon.descriptor.PortletPreferencesDescriptor;
025: import com.sun.portal.portletcontainercommon.descriptor.PortletsDescriptor;
026:
027: import javax.portlet.PortalContext;
028: import javax.portlet.Portlet;
029: import javax.portlet.PortletConfig;
030: import javax.portlet.PortletContext;
031: import javax.portlet.PortletException;
032: import javax.portlet.PreferencesValidator;
033: import javax.portlet.UnavailableException;
034: import javax.servlet.ServletContext;
035: import java.io.InputStream;
036: import java.util.HashMap;
037: import java.util.Iterator;
038: import java.util.LinkedHashMap;
039: import java.util.List;
040: import java.util.Map;
041: import java.util.logging.Level;
042: import java.util.logging.Logger;
043:
044: /**
045: * The lifecycle manager impl class is the implementation of lifecycle
046: * manager. It does the real work of creating objects maintained by the
047: * lifecycle manager.
048: * <P>
049: * There are three objects the lifecycle manager maintains:
050: * <UL>
051: * <LI>The deployment descriptor
052: * <LI>The portlet context
053: * <LI>The portlet objects
054: * </UL>
055: * The clients can call the following interface to get these three objects in the
056: * lifecycle of the portlet application:
057: * <UL>
058: * <LI><code>getDeploymentDescriptor()</code>: gets the deployment descriptor
059: * <LI><code>getPortlet(String portletName)</code>: gets the specific portlet
060: * <LI><code>getPortletContext(InputStream in)</code>: gets the portlet context
061: * <LI><code>getPreferencesValidator(String portletName)</code>:
062: * gets the preferences validator if it is defined in the deployment descriptor
063: * </UL>
064: */
065: public class LifecycleManagerImpl implements LifecycleManager {
066:
067: private PortletAppDescriptor _portletAppDescriptor;
068: private PortletContext _portletContext;
069: private static Logger _logger = PortalLogger
070: .getLogger(LifecycleManagerImpl.class);
071: private Map _portlets = new HashMap();
072: private Map _portletConfigs = new HashMap();
073: private Map _validators = new HashMap();
074: private PortalContext _portalContext;
075:
076: /**
077: * Initialize the portlet context object and the deployment descriptor
078: * object.
079: * <P>
080: * @param context The servlet context
081: */
082: public LifecycleManagerImpl(ServletContext context) {
083: //initialize the logger
084: //reads in deployment descriptor
085: InputStream xmlStream = context
086: .getResourceAsStream("/WEB-INF/portlet.xml");
087: InputStream xmlExtStream = context
088: .getResourceAsStream("/WEB-INF/sun-portlet.xml");
089: String schemaLocation = context
090: .getInitParameter(DeploymentDescriptorReader.PORTLET_SCHEMA_LOCATION);
091:
092: _portletAppDescriptor = initDeploymentDescriptor(xmlStream,
093: xmlExtStream, schemaLocation);
094:
095: //Set consumes and generates list on Servlet Context
096: /*context.setAttribute("GENERATE_EVENT_LIST",
097: _portletAppDescriptor.getPortletsDescriptor().getGeneratedEvents());
098: context.setAttribute("CONSUME_EVENT_LIST",
099: _portletAppDescriptor.getPortletsDescriptor().getConsumeEvents());*/
100: //creates portal context
101: _portalContext = initPortalContext();
102:
103: if (_portletAppDescriptor != null) {
104:
105: //creates portlet context
106: _portletContext = initPortletContext(context);
107:
108: //create porlets
109: createPortlets();
110: }
111:
112: }
113:
114: public LinkedHashMap getGeneratedEvents() {
115: return _portletAppDescriptor.getPortletsDescriptor()
116: .getGeneratedEvents();
117: }
118:
119: public LinkedHashMap getConsumeEvents() {
120: return _portletAppDescriptor.getPortletsDescriptor()
121: .getConsumeEvents();
122: }
123:
124: /*
125: * Initialize the portlet context object.
126: * <P>
127: */
128: private PortletContext initPortletContext(ServletContext context) {
129: return new PortletContextImpl(context, _portletAppDescriptor);
130: }
131:
132: /*
133: * Initialize the portal context object.
134: * <P>
135: */
136: private PortalContext initPortalContext() {
137: return new PortalContextImpl();
138: }
139:
140: /*
141: * Initialize the deployment descriptor object.
142: * <P>
143: */
144: private PortletAppDescriptor initDeploymentDescriptor(
145: InputStream xmlStream, InputStream xmlExtStream,
146: String schemaLocation) {
147: DeploymentDescriptorReader reader = new DeploymentDescriptorReader(
148: _logger, schemaLocation);
149: PortletAppDescriptor portletAppDescriptor = null;
150:
151: try {
152: portletAppDescriptor = reader.loadPortletAppDescriptor(
153: xmlStream, xmlExtStream);
154: } catch (DeploymentDescriptorException de) {
155: // do nothing, null will be return
156: }
157: return portletAppDescriptor;
158: }
159:
160: public PortletAppDescriptor getDeploymentDescriptor() {
161: return _portletAppDescriptor;
162: }
163:
164: public Portlet getPortlet(String portletName)
165: throws PortletException {
166: Portlet p = (Portlet) _portlets.get(portletName);
167:
168: if (p == null) {
169: _logger.log(Level.FINER, "PSPL_PAECSPPAI0009", portletName);
170: throw new PortletException(
171: "LifecycleManagerImpl.getPortlet(), can not get portlet.");
172: }
173:
174: return p;
175: }
176:
177: public PreferencesValidator getPreferencesValidator(
178: String portletName) {
179: return (PreferencesValidator) _validators.get(portletName);
180: }
181:
182: public void removePortlet(String portletName) {
183: Portlet p = (Portlet) _portlets.get(portletName);
184: if (p != null) {
185: synchronized (_portlets) {
186: _portlets.put(portletName, null);
187: }
188: }
189: }
190:
191: public PortletConfig getPortletConfig(String portletName) {
192: PortletConfig config = (PortletConfig) _portletConfigs
193: .get(portletName);
194:
195: if (config == null) {
196: _logger.log(Level.FINER, "PSPL_PAECSPPAI0009", portletName);
197: }
198:
199: return config;
200: }
201:
202: public void removePortletConfig(String portletName) {
203: PortletConfig config = (PortletConfig) _portletConfigs
204: .get(portletName);
205: if (config != null) {
206: synchronized (_portletConfigs) {
207: _portletConfigs.put(portletName, null);
208: }
209: }
210:
211: }
212:
213: public PortletContext getPortletContext() {
214: return _portletContext;
215: }
216:
217: public PortalContext getPortalContext() {
218: return _portalContext;
219: }
220:
221: public Logger getLogger() {
222: return _logger;
223: }
224:
225: /**
226: * Clears the portlet context object and the deployment descriptor object.
227: * Calls the <code>destroy()</code> method for each portlet object and
228: * remove it from the portlet object map.
229: */
230: public void destroy() {
231: _portletAppDescriptor = null;
232: _portletContext = null;
233:
234: //calls portlets' destroy method
235: for (Iterator i = _portlets.keySet().iterator(); i.hasNext();) {
236: String portletName = (String) i.next();
237: Portlet p = (Portlet) _portlets.get(portletName);
238: try {
239: p.destroy();
240: } catch (RuntimeException re) {
241: _logger.log(Level.FINE, "PSPL_PAECSPPAI0010",
242: portletName);
243: }
244: }
245: _portlets.clear();
246: _portletConfigs.clear();
247: _validators.clear();
248: }
249:
250: /*
251: * Creates a portlet object using the portlet class name defined in the
252: * deployment descriptor.
253: */
254: private Portlet createPortlet(String portletName,
255: PortletDescriptor portletDescriptor)
256: throws LifecycleManagerException {
257:
258: String portletClassName = portletDescriptor.getClassName();
259: Portlet portlet;
260: PreferencesValidator validator = null;
261:
262: if (portletClassName == null) {
263: throw new LifecycleManagerException(
264: "The portlet class name is not defined for portlet: "
265: + portletName);
266: } else {
267: _logger.log(Level.FINEST, "PSPL_PAECSPPAI0011",
268: portletClassName);
269: }
270:
271: try {
272: Class portletClass = Thread.currentThread()
273: .getContextClassLoader()
274: .loadClass(portletClassName);
275: portlet = (Portlet) (portletClass.newInstance());
276: PortletPreferencesDescriptor pPrefDescriptor = portletDescriptor
277: .getPortletPreferencesDescriptor();
278: if (pPrefDescriptor != null) {
279: validator = instantiatePreferencesValidator(pPrefDescriptor
280: .getPreferencesValidatorName());
281: if (validator != null) {
282: _validators.put(portletName, validator);
283: }
284: }
285: } catch (ClassNotFoundException cnfe) {
286: throw new LifecycleManagerException(cnfe);
287: } catch (IllegalAccessException iae) {
288: throw new LifecycleManagerException(iae);
289: } catch (ClassCastException cce) {
290: throw new LifecycleManagerException(cce);
291: } catch (InstantiationException ie) {
292: throw new LifecycleManagerException(ie);
293: }
294:
295: return portlet;
296:
297: }
298:
299: /*
300: * Go through the deployment descriptor and reads all the portlets,
301: * create and initialized them at one shot.
302: * <P>
303: * This method is called from the init() method of this class, which
304: * is called only once. By creating all the portlet instances
305: * at one shot, we avoid the synchronization issue about putting and
306: * getting one portlet instance from different threads, we also don't
307: * need to worry about the potential of creating multiple instances of
308: * a portlet in differnt threads.
309: * <P>
310: * There may be concern if there's a lot of portlets defined in the
311: * deployment descriptor, and if all of them are generated from the
312: * beginning and kept in memory, there is potential memory problem.
313: */
314: private void createPortlets() {
315: PortletsDescriptor portletsDescriptor = null;
316: if (_portletAppDescriptor != null) {
317: portletsDescriptor = _portletAppDescriptor
318: .getPortletsDescriptor();
319: }
320: if (portletsDescriptor != null) {
321: List names = portletsDescriptor.getPortletNames();
322: for (int i = 0; i < names.size(); i++) {
323: String portletName = (String) names.get(i);
324: PortletDescriptor portletDescriptor = portletsDescriptor
325: .getPortletDescriptor(portletName);
326: if (portletDescriptor != null) {
327: PortletConfig config = (PortletConfig) new PortletConfigImpl(
328: portletDescriptor, portletName,
329: _portletContext);
330: try {
331: Portlet p = createPortlet(portletName,
332: portletDescriptor);
333: p.init(config);
334: _portlets.put(portletName, p);
335: _portletConfigs.put(portletName, config);
336: _logger.log(Level.FINEST, "PSPL_PAECSPPAI0012",
337: portletName);
338: } catch (LifecycleManagerException lcme) {
339: _logger.log(Level.SEVERE, "PSPL_PAECSPPAI0013",
340: lcme);
341: } catch (UnavailableException ue) {
342: _logger.log(Level.SEVERE, "PSPL_PAECSPPAI0013",
343: ue);
344: } catch (PortletException pe) {
345: _logger.log(Level.INFO, "PSPL_PAECSPPAI0013",
346: pe);
347: } catch (Throwable e) {
348: _logger
349: .log(Level.INFO, "PSPL_PAECSPPAI0013",
350: e);
351: }
352: }
353: }
354: }
355: }
356:
357: /*
358: * Instantiates the validator class for this portlet. Returns null
359: * if having problem instantiates the class.
360: */
361: private PreferencesValidator instantiatePreferencesValidator(
362: String validatorName) {
363:
364: PreferencesValidator validator = null;
365:
366: if (validatorName != null) {
367: try {
368: //validator = (PreferencesValidator)(Class.forName(validatorName).newInstance());
369: Class validatorClass = Thread.currentThread()
370: .getContextClassLoader().loadClass(
371: validatorName);
372: validator = (PreferencesValidator) (validatorClass
373: .newInstance());
374: } catch (ClassNotFoundException cnfe) {
375: // will return null
376: } catch (IllegalAccessException iae) {
377: // will return null
378: } catch (ClassCastException cce) {
379: // will return null
380: } catch (InstantiationException ie) {
381: // will return null
382: } catch (SecurityException se) {
383: // will return null
384: }
385: }
386:
387: return validator;
388: }
389:
390: }
|