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.jetspeed.aggregator.impl;
018:
019: import java.util.Collection;
020: import java.util.HashMap;
021: import java.util.Iterator;
022: import java.util.Map;
023: import java.util.List;
024:
025: import javax.servlet.http.HttpServletRequest;
026: import javax.servlet.http.HttpServletResponse;
027:
028: import org.apache.commons.lang.StringEscapeUtils;
029: import org.apache.commons.logging.Log;
030: import org.apache.commons.logging.LogFactory;
031: import org.apache.jetspeed.JetspeedActions;
032: import org.apache.jetspeed.PortalReservedParameters;
033: import org.apache.jetspeed.aggregator.ContentDispatcher;
034: import org.apache.jetspeed.aggregator.ContentDispatcherCtrl;
035: import org.apache.jetspeed.aggregator.FailedToRenderFragmentException;
036: import org.apache.jetspeed.aggregator.PortletAccessDeniedException;
037: import org.apache.jetspeed.aggregator.PortletContent;
038: import org.apache.jetspeed.aggregator.PortletRenderer;
039: import org.apache.jetspeed.aggregator.PortletTrackingManager;
040: import org.apache.jetspeed.aggregator.RenderingJob;
041: import org.apache.jetspeed.aggregator.UnknownPortletDefinitionException;
042: import org.apache.jetspeed.aggregator.WorkerMonitor;
043: import org.apache.jetspeed.cache.CacheElement;
044: import org.apache.jetspeed.cache.ContentCacheKey;
045: import org.apache.jetspeed.cache.JetspeedCache;
046: import org.apache.jetspeed.components.portletentity.PortletEntityNotStoredException;
047: import org.apache.jetspeed.container.window.FailedToRetrievePortletWindow;
048: import org.apache.jetspeed.container.window.PortletWindowAccessor;
049: import org.apache.jetspeed.om.common.LocalizedField;
050: import org.apache.jetspeed.om.common.portlet.MutablePortletEntity;
051: import org.apache.jetspeed.om.common.portlet.PortletDefinitionComposite;
052: import org.apache.jetspeed.om.page.ContentFragment;
053: import org.apache.jetspeed.om.window.impl.PortletWindowImpl;
054: import org.apache.jetspeed.request.RequestContext;
055: import org.apache.jetspeed.security.SecurityAccessController;
056: import org.apache.jetspeed.services.title.DynamicTitleService;
057: import org.apache.jetspeed.statistics.PortalStatistics;
058: import org.apache.pluto.PortletContainer;
059: import org.apache.pluto.om.entity.PortletEntity;
060: import org.apache.pluto.om.window.PortletWindow;
061:
062: /**
063: * <h4>PortletRendererService <br />
064: * Jetspeed-2 Rendering service.</h4>
065: * <p>
066: * This service process all portlet rendering requests and interfaces with the
067: * portlet container to generate the resulting markup
068: * </p>
069: *
070: * @author <a href="mailto:raphael@apache.org">Rapha�l Luta </a>
071: * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
072: * @author <a>Woonsan Ko</a>
073: * @version $Id: PortletRendererImpl.java,v 1.30 2005/05/20 14:54:22 ate Exp $
074: */
075: public class PortletRendererImpl implements PortletRenderer {
076: protected final static Log log = LogFactory
077: .getLog(PortletRendererImpl.class);
078:
079: protected WorkerMonitor workMonitor;
080: protected PortletContainer container;
081: protected PortletWindowAccessor windowAccessor;
082: protected PortalStatistics statistics;
083: protected DynamicTitleService addTitleService;
084:
085: protected PortletTrackingManager portletTracking;
086:
087: /**
088: * flag indicating whether to check jetspeed-portlet.xml security constraints
089: * before rendering a portlet. If security check fails, do not display portlet content
090: */
091: protected boolean checkSecurityConstraints;
092: /**
093: * For security constraint checks
094: */
095: protected SecurityAccessController accessController;
096:
097: /**
098: * JSR 168 Portlet Content Cache
099: */
100: protected JetspeedCache portletContentCache;
101:
102: /**
103: * OutOfService Cache
104: */
105: protected boolean overrideTitles = false;
106: public static final String OUT_OF_SERVICE_MESSAGE = "Portlet is not responding and has been taken out of service.";
107:
108: public PortletRendererImpl(PortletContainer container,
109: PortletWindowAccessor windowAccessor,
110: WorkerMonitor workMonitor, PortalStatistics statistics,
111: DynamicTitleService addTitleService,
112: PortletTrackingManager portletTracking,
113: boolean checkSecurityConstraints,
114: SecurityAccessController accessController,
115: JetspeedCache portletContentCache, boolean overrideTitles) {
116: this .container = container;
117: this .windowAccessor = windowAccessor;
118: this .workMonitor = workMonitor;
119: this .statistics = statistics;
120: this .addTitleService = addTitleService;
121: this .portletTracking = portletTracking;
122: this .checkSecurityConstraints = checkSecurityConstraints;
123: this .accessController = accessController;
124: this .portletContentCache = portletContentCache;
125: this .overrideTitles = overrideTitles;
126: }
127:
128: public PortletRendererImpl(PortletContainer container,
129: PortletWindowAccessor windowAccessor,
130: WorkerMonitor workMonitor, PortalStatistics statistics,
131: DynamicTitleService addTitleService,
132: PortletTrackingManager portletTracking,
133: boolean checkSecurityConstraints,
134: SecurityAccessController accessController,
135: JetspeedCache portletContentCache) {
136: this (container, windowAccessor, workMonitor, statistics,
137: addTitleService, portletTracking,
138: checkSecurityConstraints, accessController,
139: portletContentCache, false);
140: }
141:
142: public PortletRendererImpl(PortletContainer container,
143: PortletWindowAccessor windowAccessor,
144: WorkerMonitor workMonitor, PortalStatistics statistics,
145: DynamicTitleService addTitleService) {
146: this (container, windowAccessor, workMonitor, statistics, null,
147: null, false, null, null, true);
148: }
149:
150: public PortletRendererImpl(PortletContainer container,
151: PortletWindowAccessor windowAccessor,
152: WorkerMonitor workMonitor, PortalStatistics statistics) {
153: this (container, windowAccessor, workMonitor, statistics, null);
154: }
155:
156: public PortletRendererImpl(PortletContainer container,
157: PortletWindowAccessor windowAccessor,
158: WorkerMonitor workMonitor) {
159: this (container, windowAccessor, workMonitor, null);
160: }
161:
162: public void start() {
163: // workMonitor.start();
164: }
165:
166: public void stop() {
167: // this.monitor.shutdown ?
168: }
169:
170: /**
171: * Render the specified Page fragment. Result is returned in the
172: * PortletResponse.
173: *
174: * @throws FailedToRenderFragmentException
175: * @throws FailedToRetrievePortletWindow
176: * @throws UnknownPortletDefinitionException
177: */
178: public void renderNow(ContentFragment fragment,
179: RequestContext requestContext) {
180: HttpServletRequest servletRequest = null;
181: HttpServletResponse servletResponse = null;
182: ContentDispatcherCtrl dispatcher = null;
183: boolean contentIsCached = false;
184: try {
185: PortletWindow portletWindow = getPortletWindow(fragment);
186: PortletDefinitionComposite portletDefinition = (PortletDefinitionComposite) portletWindow
187: .getPortletEntity().getPortletDefinition();
188: if (checkSecurityConstraints
189: && !checkSecurityConstraint(portletDefinition,
190: fragment)) {
191: throw new PortletAccessDeniedException("Access Denied.");
192: }
193: if (portletTracking.isOutOfService(portletWindow)) {
194: log.info("Taking portlet out of service: "
195: + portletDefinition.getUniqueName()
196: + " for window " + fragment.getId());
197: fragment
198: .overrideRenderedContent(OUT_OF_SERVICE_MESSAGE);
199: return;
200: }
201: long timeoutMetadata = this
202: .getTimeoutOnJob(portletDefinition);
203: portletTracking.setExpiration(portletWindow,
204: timeoutMetadata);
205: int expirationCache = getExpirationCache(portletDefinition);
206: if (expirationCache != 0) {
207: if (retrieveCachedContent(requestContext, fragment,
208: portletWindow, expirationCache,
209: portletDefinition))
210: return;
211: contentIsCached = true;
212: }
213: if (dispatcher == null) {
214: dispatcher = createDispatcher(requestContext, fragment,
215: expirationCache);
216: }
217: servletRequest = requestContext
218: .getRequestForWindow(portletWindow);
219: servletResponse = dispatcher.getResponseForWindow(
220: portletWindow, requestContext);
221: RenderingJob rJob = buildRenderingJob(portletWindow,
222: fragment, servletRequest, servletResponse,
223: requestContext, false, portletDefinition,
224: dispatcher, null, expirationCache, contentIsCached,
225: timeoutMetadata);
226: rJob.execute();
227: addTitleToHeader(portletWindow, fragment, servletRequest,
228: servletResponse, dispatcher, contentIsCached);
229: } catch (PortletAccessDeniedException e) {
230: fragment.overrideRenderedContent(e.getLocalizedMessage());
231: } catch (Exception e) {
232: fragment.overrideRenderedContent(e.getLocalizedMessage());
233: log.error(e.toString(), e);
234: }
235: }
236:
237: /**
238: * Render the specified Page fragment. Result is returned in the
239: * PortletResponse.
240: *
241: * @throws FailedToRenderFragmentException
242: * @throws FailedToRetrievePortletWindow
243: * @throws UnknownPortletDefinitionException
244: * @throws PortletAccessDeniedException
245: */
246: public void renderNow(ContentFragment fragment,
247: HttpServletRequest request, HttpServletResponse response) {
248: RequestContext requestContext = (RequestContext) request
249: .getAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE);
250: renderNow(fragment, requestContext);
251: }
252:
253: protected int getExpirationCache(
254: PortletDefinitionComposite portletDefinition) {
255: if (portletDefinition == null)
256: return 0;
257: String expiration = portletDefinition.getExpirationCache();
258: if (expiration == null)
259: return 0;
260: return Integer.parseInt(expiration);
261: }
262:
263: /**
264: * Render the specified Page fragment. The method returns before rendering
265: * is complete, rendered content can be accessed through the Content Dispatcher
266: *
267: * @return the asynchronous portlet rendering job to synchronize
268: */
269: public RenderingJob render(ContentFragment fragment,
270: RequestContext requestContext) {
271: RenderingJob job = null;
272:
273: try {
274: job = createRenderingJob(fragment, requestContext);
275: } catch (Exception e) {
276: log.error("render() failed: " + e.toString(), e);
277: fragment.overrideRenderedContent(e.getLocalizedMessage());
278: }
279:
280: if (job != null) {
281: processRenderingJob(job, true);
282: }
283:
284: return job;
285: }
286:
287: /**
288: *
289: * Create a rendering job for the specified Page fragment.
290: * The method returns a rendering job which should be passed to 'processRenderingJob(RenderingJob job)' method.
291: * @return portlet rendering job to pass to render(RenderingJob job) method
292: * @throws FailedToRetrievePortletWindow
293: * @throws UnknownPortletDefinitionException
294: * @throws PortletAccessDeniedException
295: */
296: public RenderingJob createRenderingJob(ContentFragment fragment,
297: RequestContext requestContext) {
298: RenderingJob job = null;
299: boolean contentIsCached = false;
300: try {
301: PortletWindow portletWindow = getPortletWindow(fragment);
302: PortletDefinitionComposite portletDefinition = (PortletDefinitionComposite) portletWindow
303: .getPortletEntity().getPortletDefinition();
304:
305: long timeoutMetadata = this
306: .getTimeoutOnJob(portletDefinition);
307: portletTracking.setExpiration(portletWindow,
308: timeoutMetadata);
309:
310: if (checkSecurityConstraints
311: && !checkSecurityConstraint(portletDefinition,
312: fragment)) {
313: throw new PortletAccessDeniedException("Access Denied.");
314: }
315: if (portletTracking.isOutOfService(portletWindow)) {
316: fragment
317: .overrideRenderedContent(OUT_OF_SERVICE_MESSAGE);
318: return null;
319: }
320: int expirationCache = getExpirationCache(portletDefinition);
321: if (expirationCache != 0) {
322: portletTracking.setExpiration(portletWindow,
323: expirationCache);
324: contentIsCached = retrieveCachedContent(requestContext,
325: fragment, portletWindow, expirationCache,
326: portletDefinition);
327: if (contentIsCached) {
328: return null;
329: }
330: }
331: job = buildRenderingJob(portletWindow, fragment,
332: requestContext, true, portletDefinition, null,
333: contentIsCached, timeoutMetadata);
334: } catch (Exception e) {
335: throw new RuntimeException(
336: "Failed to create rendering job", e);
337: }
338:
339: return job;
340: }
341:
342: /**
343: *
344: * Render the specified rendering job.
345: * The method returns before rendering is complete when the job is processed in parallel mode.
346: * When it is not parallel mode, it returns after rendering is complete.
347: * @throws FailedToRenderFragmentException
348: */
349: public void processRenderingJob(RenderingJob job) {
350: processRenderingJob(job, false);
351: }
352:
353: protected void processRenderingJob(RenderingJob job,
354: boolean parallelOnly) {
355: ContentFragment fragment = null;
356:
357: try {
358: if (parallelOnly || job.getTimeout() > 0) {
359: workMonitor.process(job);
360: } else {
361: job.execute();
362: addTitleToHeader(job.getWindow(), job.getFragment(),
363: job.getRequest(), job.getResponse(), job
364: .getDispatcher(), job.isContentCached());
365: }
366: } catch (Exception e1) {
367: log.error("render() failed: " + e1.toString(), e1);
368: fragment.overrideRenderedContent(e1.getLocalizedMessage());
369: }
370: }
371:
372: /**
373: * Wait for all rendering jobs in the collection to finish successfully or otherwise.
374: * @param renderingJobs the Collection of rendering job objects to wait for.
375: */
376: public void waitForRenderingJobs(List renderingJobs) {
377: this .workMonitor.waitForRenderingJobs(renderingJobs);
378: }
379:
380: /**
381: * Retrieve cached content, if content retrieved successfully return true, if no content found return false
382: * @param requestContext
383: * @param fragment
384: * @param portletWindow
385: * @return true when content found, otherwise false
386: */
387: protected boolean retrieveCachedContent(
388: RequestContext requestContext, ContentFragment fragment,
389: PortletWindow portletWindow, int expiration,
390: PortletDefinitionComposite portletDefinition)
391: throws Exception {
392: ContentCacheKey cacheKey = portletContentCache.createCacheKey(
393: requestContext, fragment.getId());
394: CacheElement cachedElement = portletContentCache.get(cacheKey);
395: if (cachedElement != null) {
396: PortletContent portletContent = (PortletContent) cachedElement
397: .getContent();
398: fragment.setPortletContent(portletContent);
399: ContentDispatcherCtrl dispatcher = new ContentDispatcherImpl(
400: portletContent);
401: HttpServletRequest servletRequest = requestContext
402: .getRequestForWindow(portletWindow);
403:
404: this .addTitleService.setDynamicTitle(portletWindow,
405: servletRequest, dispatcher.getPortletContent(
406: fragment).getTitle());
407: return true;
408: }
409: return false;
410: }
411:
412: public ContentDispatcherCtrl createDispatcher(
413: RequestContext request, ContentFragment fragment,
414: int expirationCache) {
415: ContentCacheKey cacheKey = portletContentCache.createCacheKey(
416: request, fragment.getId());
417: PortletContent content = new PortletContentImpl(this , cacheKey,
418: expirationCache);
419: ContentDispatcherCtrl dispatcher = new ContentDispatcherImpl(
420: content);
421: return dispatcher;
422: }
423:
424: /**
425: * Retrieve the ContentDispatcher for the specified request
426: */
427: public ContentDispatcher getDispatcher(RequestContext request,
428: boolean isParallel) {
429: return request.getContentDispatcher();
430: }
431:
432: protected PortletWindow getPortletWindow(ContentFragment fragment)
433: throws FailedToRetrievePortletWindow,
434: PortletEntityNotStoredException {
435: // ObjectID oid = JetspeedObjectID.createFromString(fragment.getId());
436: PortletWindow portletWindow = windowAccessor
437: .getPortletWindow(fragment);
438:
439: if (portletWindow == null) {
440: throw new FailedToRetrievePortletWindow(
441: "Portlet Window creation failed for fragment: "
442: + fragment.getId() + ", "
443: + fragment.getName());
444: }
445:
446: PortletEntity portletEntity = portletWindow.getPortletEntity();
447: ((MutablePortletEntity) portletEntity).setFragment(fragment);
448:
449: ((PortletWindowImpl) portletWindow)
450: .setInstantlyRendered(fragment.isInstantlyRendered());
451:
452: return portletWindow;
453: }
454:
455: protected RenderingJob buildRenderingJob(
456: PortletWindow portletWindow, ContentFragment fragment,
457: RequestContext requestContext, boolean isParallel,
458: PortletDefinitionComposite portletDefinition,
459: PortletContent portletContent, boolean contentIsCached,
460: long timeoutMetadata) throws PortletAccessDeniedException,
461: FailedToRetrievePortletWindow,
462: PortletEntityNotStoredException {
463: int expirationCache = getExpirationCache(portletDefinition);
464: ContentDispatcherCtrl dispatcher = createDispatcher(
465: requestContext, fragment, expirationCache);
466: HttpServletRequest request = requestContext
467: .getRequestForWindow(portletWindow);
468: HttpServletResponse response = dispatcher.getResponseForWindow(
469: portletWindow, requestContext);
470:
471: return buildRenderingJob(portletWindow, fragment, request,
472: response, requestContext, isParallel,
473: portletDefinition, dispatcher, portletContent,
474: expirationCache, contentIsCached, timeoutMetadata);
475: }
476:
477: protected RenderingJob buildRenderingJob(
478: PortletWindow portletWindow, ContentFragment fragment,
479: HttpServletRequest request, HttpServletResponse response,
480: RequestContext requestContext, boolean isParallel,
481: PortletDefinitionComposite portletDefinition,
482: ContentDispatcherCtrl dispatcher,
483: PortletContent portletContent, int expirationCache,
484: boolean contentIsCached, long timeoutMetadata)
485: throws PortletAccessDeniedException,
486: FailedToRetrievePortletWindow,
487: PortletEntityNotStoredException {
488: RenderingJob rJob = null;
489:
490: request.setAttribute(PortalReservedParameters.PAGE_ATTRIBUTE,
491: requestContext.getPage());
492: request.setAttribute(
493: PortalReservedParameters.FRAGMENT_ATTRIBUTE, fragment);
494: request.setAttribute(
495: PortalReservedParameters.CONTENT_DISPATCHER_ATTRIBUTE,
496: dispatcher);
497: request.setAttribute(
498: PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE,
499: requestContext);
500: request.setAttribute(
501: PortalReservedParameters.REQUEST_CONTEXT_OBJECTS,
502: requestContext.getObjects());
503: request
504: .setAttribute(
505: PortalReservedParameters.PATH_ATTRIBUTE,
506: requestContext
507: .getAttribute(PortalReservedParameters.PATH_ATTRIBUTE));
508: request.setAttribute(
509: PortalReservedParameters.PORTLET_WINDOW_ATTRIBUTE,
510: portletWindow);
511:
512: if (portletContent == null) {
513: portletContent = dispatcher.getPortletContent(fragment);
514: fragment.setPortletContent(portletContent);
515: }
516: // In case of parallel mode, store attributes in a map to be refered by worker.
517: if (isParallel) {
518: Map workerAttrs = new HashMap();
519: workerAttrs.put(PortalReservedParameters.PAGE_ATTRIBUTE,
520: requestContext.getPage());
521: workerAttrs.put(
522: PortalReservedParameters.FRAGMENT_ATTRIBUTE,
523: fragment);
524: workerAttrs
525: .put(
526: PortalReservedParameters.CONTENT_DISPATCHER_ATTRIBUTE,
527: dispatcher);
528: workerAttrs.put(
529: PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE,
530: requestContext);
531: workerAttrs.put(
532: PortalReservedParameters.REQUEST_CONTEXT_OBJECTS,
533: requestContext.getObjects());
534: workerAttrs
535: .put(
536: PortalReservedParameters.PATH_ATTRIBUTE,
537: requestContext
538: .getAttribute(PortalReservedParameters.PATH_ATTRIBUTE));
539: workerAttrs.put(
540: PortalReservedParameters.PORTLET_WINDOW_ATTRIBUTE,
541: portletWindow);
542:
543: // the portlet invoker is not thread safe; it stores current portlet definition as a member variable.
544: // so, store portlet definition as an attribute of worker
545: workerAttrs
546: .put(
547: PortalReservedParameters.PORTLET_DEFINITION_ATTRIBUTE,
548: portletDefinition);
549:
550: rJob = new RenderingJobImpl(container, this ,
551: portletDefinition, portletContent, fragment,
552: dispatcher, request, response, requestContext,
553: portletWindow, statistics, expirationCache,
554: contentIsCached, workerAttrs);
555:
556: } else {
557: rJob = new RenderingJobImpl(container, this ,
558: portletDefinition, portletContent, fragment,
559: dispatcher, request, response, requestContext,
560: portletWindow, statistics, expirationCache,
561: contentIsCached);
562:
563: }
564:
565: if (isParallel) {
566: setTimeoutOnJob(timeoutMetadata, rJob);
567: }
568:
569: return rJob;
570: }
571:
572: protected long getTimeoutOnJob(
573: PortletDefinitionComposite portletDefinition) {
574: long timeoutMetadata = 0;
575: Collection timeoutFields = null;
576:
577: if (portletDefinition != null) {
578: timeoutFields = portletDefinition
579: .getMetadata()
580: .getFields(
581: PortalReservedParameters.PORTLET_EXTENDED_DESCRIPTOR_RENDER_TIMEOUT);
582: }
583:
584: if (timeoutFields != null) {
585: Iterator it = timeoutFields.iterator();
586:
587: if (it.hasNext()) {
588: LocalizedField timeoutField = (LocalizedField) timeoutFields
589: .iterator().next();
590:
591: try {
592: timeoutMetadata = Long.parseLong(timeoutField
593: .getValue());
594: } catch (NumberFormatException nfe) {
595: log.warn("Invalid timeout metadata: "
596: + nfe.getMessage());
597: }
598: }
599: }
600: return timeoutMetadata;
601: }
602:
603: protected void setTimeoutOnJob(long timeoutMetadata,
604: RenderingJob rJob) {
605:
606: if (timeoutMetadata > 0) {
607: rJob.setTimeout(timeoutMetadata);
608: } else if (this .portletTracking.getDefaultPortletTimeout() > 0) {
609: rJob.setTimeout(this .portletTracking
610: .getDefaultPortletTimeout());
611: }
612: }
613:
614: public void addTitleToHeader(PortletWindow portletWindow,
615: ContentFragment fragment, HttpServletRequest request,
616: HttpServletResponse response,
617: ContentDispatcherCtrl dispatcher, boolean isCacheTitle) {
618: if (overrideTitles) {
619: try {
620: String title = fragment.getTitle();
621:
622: if (title == null) {
623: title = addTitleService.getDynamicTitle(
624: portletWindow, request);
625: }
626:
627: response.setHeader("JS_PORTLET_TITLE",
628: StringEscapeUtils.escapeHtml(title));
629: dispatcher.getPortletContent(fragment).setTitle(title);
630: } catch (Exception e) {
631: log.error("Unable to reteive portlet title: "
632: + e.getMessage(), e);
633: }
634: } else {
635: String title = null;
636:
637: if (isCacheTitle) {
638: title = fragment.getTitle();
639:
640: if (title == null) {
641: title = addTitleService.getDynamicTitle(
642: portletWindow, request);
643: }
644:
645: dispatcher.getPortletContent(fragment).setTitle(title);
646: }
647:
648: if (title == null) {
649: title = addTitleService.getDynamicTitle(portletWindow,
650: request);
651: dispatcher.getPortletContent(fragment).setTitle(title);
652: }
653: }
654: }
655:
656: protected boolean checkSecurityConstraint(
657: PortletDefinitionComposite portlet, ContentFragment fragment) {
658: if (fragment.getType().equals(ContentFragment.PORTLET)) {
659: if (accessController != null) {
660: return accessController.checkPortletAccess(portlet,
661: JetspeedActions.MASK_VIEW);
662: }
663: }
664: return true;
665: }
666:
667: protected void addToCache(PortletContent content) {
668: CacheElement cachedElement = portletContentCache.createElement(
669: content.getCacheKey(), content);
670: if (content.getExpiration() == -1) {
671: cachedElement.setTimeToIdleSeconds(portletContentCache
672: .getTimeToIdleSeconds());
673: cachedElement.setTimeToLiveSeconds(portletContentCache
674: .getTimeToLiveSeconds());
675: } else {
676: cachedElement.setTimeToIdleSeconds(content.getExpiration());
677: cachedElement.setTimeToLiveSeconds(content.getExpiration());
678: }
679: portletContentCache.put(cachedElement);
680: }
681:
682: public void notifyContentComplete(PortletContent content) {
683: if (content.getExpiration() != 0)
684: addToCache(content);
685: }
686:
687: public PortletTrackingManager getPortletTrackingManager() {
688: return this.portletTracking;
689: }
690: }
|