1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.velocity;
18
19 import java.io.IOException;
20 import java.io.PrintWriter;
21 import java.io.Writer;
22 import java.security.Principal;
23 import java.util.HashMap;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Locale;
27 import java.util.Set;
28
29 import javax.portlet.PortletConfig;
30 import javax.portlet.PortletMode;
31 import javax.portlet.RenderRequest;
32 import javax.portlet.RenderResponse;
33 import javax.portlet.WindowState;
34 import javax.security.auth.Subject;
35 import javax.servlet.http.HttpServletRequest;
36
37 import org.apache.commons.configuration.Configuration;
38 import org.apache.commons.configuration.PropertiesConfiguration;
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41 import org.apache.jetspeed.Jetspeed;
42 import org.apache.jetspeed.PortalReservedParameters;
43 import org.apache.jetspeed.aggregator.PortletRenderer;
44 import org.apache.jetspeed.aggregator.impl.PortletAggregatorFragmentImpl;
45 import org.apache.jetspeed.capabilities.CapabilityMap;
46 import org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent;
47 import org.apache.jetspeed.components.portletentity.PortletEntityNotGeneratedException;
48 import org.apache.jetspeed.components.portletentity.PortletEntityNotStoredException;
49 import org.apache.jetspeed.container.state.NavigationalState;
50 import org.apache.jetspeed.container.url.BasePortalURL;
51 import org.apache.jetspeed.container.window.FailedToRetrievePortletWindow;
52 import org.apache.jetspeed.container.window.PortletWindowAccessor;
53 import org.apache.jetspeed.locator.LocatorDescriptor;
54 import org.apache.jetspeed.locator.TemplateDescriptor;
55 import org.apache.jetspeed.locator.TemplateLocator;
56 import org.apache.jetspeed.locator.TemplateLocatorException;
57 import org.apache.jetspeed.om.page.ContentFragment;
58 import org.apache.jetspeed.om.page.ContentFragmentImpl;
59 import org.apache.jetspeed.om.page.Fragment;
60 import org.apache.jetspeed.om.page.Page;
61 import org.apache.jetspeed.request.RequestContext;
62 import org.apache.jetspeed.services.title.DynamicTitleService;
63 import org.apache.jetspeed.util.ArgUtil;
64 import org.apache.jetspeed.util.Path;
65 import org.apache.pluto.om.entity.PortletEntity;
66 import org.apache.velocity.context.Context;
67
68 /***
69 * <p>
70 * JetspeedPowerTool
71 * </p>
72 * <p>
73 * The JetspeedPowerTool is meant to be used by template designers to build
74 * templates for internal Jetspeed portlet applications. It hides the
75 * implementation details of the more common template actions so that future
76 * changes to said implementation have minimal effect on template.
77 * </p>
78 * <p>
79 * Where applicable, methods have been marked with a <strong>BEST PRATICES
80 * </strong> meaning that this method should be used instead the synonymous code
81 * listed within the method docuementation.
82 * </p>
83 *
84 * @author <a href="mailto:weaver@apache.org">Scott T. Weaver </a>
85 * @version $Id: JetspeedPowerToolImpl.java 589933 2007-10-30 01:51:50Z woonsan $
86 *
87 */
88 public class JetspeedPowerToolImpl implements JetspeedVelocityPowerTool
89 {
90
91 private static final String DECORATOR_ID_ATTR = "decoratorId";
92
93 private static final String ACTION_IMAGE_EXTENSION_ATTR = "actionImageExtension";
94
95 protected static final String PORTLET_CONFIG_ATTR = "javax.portlet.config";
96
97 protected static final String RENDER_RESPONSE_ATTR = "javax.portlet.response";
98
99 protected static final String RENDER_REQUEST_ATTR = "javax.portlet.request";
100
101 protected static final String COLUMNS_ATTR = "columns";
102
103 protected static final String COLUMN_SIZES = "columnSizes";
104
105 protected RenderRequest renderRequest;
106
107 protected RenderResponse renderResponse;
108
109 protected PortletConfig portletConfig;
110
111 protected Writer templateWriter;
112
113 protected static final Log log = LogFactory.getLog(JetspeedPowerToolImpl.class);
114
115 protected CapabilityMap capabilityMap;
116
117 protected Locale locale;
118
119 protected LocatorDescriptor templateLocatorDescriptor;
120
121 protected TemplateLocator templateLocator;
122
123 protected PortletEntityAccessComponent entityAccess;
124
125 protected TemplateLocator decorationLocator;
126
127 protected LocatorDescriptor decorationLocatorDescriptor;
128
129 protected PortletWindowAccessor windowAccess;
130
131 protected RequestContext requestContext;
132
133 protected Context velocityContext;
134
135 private DynamicTitleService titleService;
136
137 private BasePortalURL baseUrlAccess;
138
139 private PortletRenderer renderer;
140
141 public JetspeedPowerToolImpl(RequestContext requestContext, DynamicTitleService titleService,PortletRenderer renderer) throws Exception
142 {
143 HttpServletRequest request = requestContext.getRequest();
144 this.requestContext = requestContext;
145 this.titleService = titleService;
146 windowAccess = (PortletWindowAccessor) getComponent(PortletWindowAccessor.class.getName());
147 entityAccess = (PortletEntityAccessComponent) getComponent(PortletEntityAccessComponent.class.getName());
148 try
149 {
150 baseUrlAccess = (BasePortalURL) getComponent("BasePortalURL");
151 }
152 catch (Exception e)
153 {
154
155 }
156
157 renderRequest = (RenderRequest) request.getAttribute(RENDER_REQUEST_ATTR);
158 renderResponse = (RenderResponse) request.getAttribute(RENDER_RESPONSE_ATTR);
159 portletConfig = (PortletConfig) request.getAttribute(PORTLET_CONFIG_ATTR);
160
161
162 templateLocator = (TemplateLocator) getComponent("TemplateLocator");
163 decorationLocator = (TemplateLocator) getComponent("DecorationLocator");
164
165 capabilityMap = requestContext.getCapabilityMap();
166 locale = requestContext.getLocale();
167
168 templateLocatorDescriptor = templateLocator.createLocatorDescriptor(null);
169 templateLocatorDescriptor.setMediaType(capabilityMap.getPreferredMediaType().getName());
170 templateLocatorDescriptor.setCountry(locale.getCountry());
171 templateLocatorDescriptor.setLanguage(locale.getLanguage());
172
173 decorationLocatorDescriptor = decorationLocator.createLocatorDescriptor(null);
174 decorationLocatorDescriptor.setMediaType(capabilityMap.getPreferredMediaType().getName());
175 decorationLocatorDescriptor.setCountry(locale.getCountry());
176 decorationLocatorDescriptor.setLanguage(locale.getLanguage());
177
178 this.renderer = renderer;
179 }
180
181 /***
182 * <p>
183 * getRequestContext
184 * </p>
185 *
186 * @return
187 */
188 protected final RequestContext getRequestContext()
189 {
190 return requestContext;
191 }
192
193 /***
194 * Gets the window state for the current portlet window (fragment)
195 *
196 * @return The window state for the current window
197 * @throws Exception
198 */
199 public WindowState getWindowState() throws Exception
200 {
201 try
202 {
203 NavigationalState nav = getRequestContext().getPortalURL().getNavigationalState();
204 return nav.getState(windowAccess.getPortletWindow(getCurrentFragment()));
205 }
206 catch (Exception e)
207 {
208 handleError(e, e.toString(), getCurrentFragment());
209 return null;
210 }
211 }
212
213 /***
214 * Gets the internal (portal) window state for the current portlet window (fragment)
215 *
216 * @return The window state for the current window
217 * @throws Exception
218 */
219 public WindowState getMappedWindowState() throws Exception
220 {
221 try
222 {
223 NavigationalState nav = getRequestContext().getPortalURL().getNavigationalState();
224 return nav.getMappedState(windowAccess.getPortletWindow(getCurrentFragment()));
225 }
226 catch (Exception e)
227 {
228 handleError(e, e.toString(), getCurrentFragment());
229 return null;
230 }
231 }
232
233 /***
234 * Gets the portlet mode for a current portlet window (fragment)
235 *
236 * @return The portlet mode of the current window
237 * @throws Exception
238 */
239 public PortletMode getPortletMode() throws Exception
240 {
241
242 NavigationalState nav = getRequestContext().getPortalURL().getNavigationalState();
243 try
244 {
245 return nav.getMode(windowAccess.getPortletWindow(getCurrentFragment()));
246 }
247 catch (FailedToRetrievePortletWindow e)
248 {
249 handleError(e, e.toString(), getCurrentFragment());
250 return null;
251 }
252 }
253
254 /***
255 * Gets the internal (portal) portlet mode for a current portlet window (fragment)
256 *
257 * @return The portlet mode of the current window
258 * @throws Exception
259 */
260 public PortletMode getMappedPortletMode() throws Exception
261 {
262
263 NavigationalState nav = getRequestContext().getPortalURL().getNavigationalState();
264 try
265 {
266 return nav.getMappedMode(windowAccess.getPortletWindow(getCurrentFragment()));
267 }
268 catch (FailedToRetrievePortletWindow e)
269 {
270 handleError(e, e.toString(), getCurrentFragment());
271 return null;
272 }
273 }
274
275 /***
276 *
277 * @return
278 */
279 public ContentFragment getCurrentFragment()
280 {
281 checkState();
282 return (ContentFragment) renderRequest.getAttribute(PortalReservedParameters.FRAGMENT_ATTRIBUTE);
283 }
284
285 /***
286 *
287 * @param f
288 */
289 public void setCurrentFragment(ContentFragment f)
290 {
291 checkState();
292 setAttribute(PortalReservedParameters.FRAGMENT_ATTRIBUTE, f);
293
294 }
295
296 public void setCurrentLayout()
297 {
298 checkState();
299
300 ContentFragment f = (ContentFragment) getRequestContext().getRequest().getAttribute(LAYOUT_ATTR);
301 setAttribute(LAYOUT_ATTR, f);
302 }
303
304 /***
305 *
306 * @return
307 */
308 public ContentFragment getCurrentLayout()
309 {
310 checkState();
311 return (ContentFragment) renderRequest.getAttribute(LAYOUT_ATTR);
312 }
313
314 /***
315 *
316 * @return
317 */
318 public Page getPage()
319 {
320 checkState();
321
322
323 return requestContext.getPage();
324 }
325
326 /***
327 *
328 * @return
329 */
330 public List[] getColumns()
331 {
332 checkState();
333 return (List[]) renderRequest.getAttribute(COLUMNS_ATTR);
334 }
335
336 public List getColumnSizes()
337 {
338 checkState();
339 Object o = renderRequest.getAttribute(COLUMN_SIZES);
340 if (o == null)
341 return null;
342 return (List) renderRequest.getAttribute(COLUMN_SIZES);
343 }
344
345 /***
346 *
347 * @return
348 * @throws Exception
349 */
350 public PortletEntity getCurrentPortletEntity() throws Exception
351 {
352 try
353 {
354 return windowAccess.getPortletWindow(getCurrentFragment()).getPortletEntity();
355 }
356 catch (Exception e)
357 {
358 handleError(e, "JetspeedPowerTool failed to retreive the current PortletEntity. " + e.toString(),
359 getCurrentFragment());
360 return null;
361 }
362 }
363
364 /***
365 *
366 * @param f
367 * Fragment whose <code>PortletEntity</code> we want to
368 * retreive.
369 * @return The PortletEntity represented by the current fragment.
370 * @throws Exception
371 */
372 public PortletEntity getPortletEntity(ContentFragment f) throws Exception
373 {
374 PortletEntity portletEntity = windowAccess.getPortletWindow(f).getPortletEntity();
375
376 if (portletEntity == null)
377 {
378 try
379 {
380 portletEntity = entityAccess.generateEntityFromFragment(f);
381 entityAccess.storePortletEntity(portletEntity);
382 }
383 catch (PortletEntityNotGeneratedException e)
384 {
385 String msg = "JetspeedPowerTool failed to retreive a PortletEntity for Fragment " + f.getId() + ". "
386 + e.toString();
387 handleError(e, msg, f);
388 }
389 catch (PortletEntityNotStoredException e)
390 {
391 String msg = "JetspeedPowerTool failed to store a PortletEntity for Fragment " + f.getId() + ". "
392 + e.toString();
393 handleError(e, msg, f);
394 }
395 }
396 return portletEntity;
397 }
398
399 /***
400 * Checks the the visibilty of this fragment with respect to the current
401 * RenderReqeust.
402 *
403 * @param f
404 * Fragment
405 * @return whether or not the Fragment in question should be considered
406 * visible during rendering.
407 */
408 public boolean isHidden(ContentFragment f)
409 {
410 checkState();
411 if (f == null)
412 {
413 throw new IllegalArgumentException("Fragment cannot be null for isHidden(Fragment)");
414 }
415 return f.getState() != null && f.getState().equals(HIDDEN);
416 }
417
418 /***
419 * Retreives a template using Jetspeed's
420 *
421 * @see org.apache.jetspeed.locator.TemplateLocator
422 *
423 *
424 * @param path
425 * Expected to the template. This may actually be changed by the
426 * TL service based the capability and localization information
427 * provided by the client.
428 * @param templateType
429 * Type off template we are interested in.
430 * @return Template object containng the pertinent information required to
431 * inlcude the request template path in the current response
432 * @throws TemplateLocatorException
433 * if the <code>path</code> does not exist.
434 */
435 public TemplateDescriptor getTemplate(String path, String templateType) throws TemplateLocatorException
436 {
437 checkState();
438 return getTemplate(path, templateType, templateLocator, templateLocatorDescriptor);
439 }
440
441 public Configuration getTypeConfiguration(String type, String name, String location) throws Exception
442 {
443 ArgUtil.assertNotNull(String.class, type, this, "getTypeConfiguration(String type, String name)");
444 ArgUtil.assertNotNull(String.class, name, this, "getTypeConfiguration(String type, String name)");
445 try
446 {
447 TemplateDescriptor locator = null;
448 if (location.equals("templates"))
449 {
450 locator = getTemplate(name + "/" + type + ".properties", type);
451 }
452 else if (location.equals("decorations"))
453 {
454 locator = getDecoration(name + "/decorator.properties", type);
455 }
456 else
457 {
458 throw new IllegalArgumentException("Location type " + location
459 + " is not supported by getTypeConfiguration().");
460 }
461 return new PropertiesConfiguration(locator.getAbsolutePath());
462 }
463 catch (TemplateLocatorException e)
464 {
465 log.warn(e.toString(), e);
466 return null;
467 }
468 }
469
470 public TemplateDescriptor getDecoration(String path, String templateType) throws TemplateLocatorException
471 {
472 checkState();
473 return getTemplate(path, templateType, decorationLocator, decorationLocatorDescriptor);
474 }
475
476 public String includeTemplate(String template, String templateType) throws IOException
477 {
478 checkState();
479 try
480 {
481 TemplateDescriptor useLocator = getTemplate(template, templateType);
482 return useLocator.getAppRelativePath();
483 }
484 catch (Exception e)
485 {
486 PrintWriter directError = new PrintWriter(renderResponse.getWriter());
487 directError.write("Error occured process includeTemplate(): " + e.toString() + "\n\n");
488 e.printStackTrace(directError);
489 directError.close();
490 return null;
491 }
492 }
493
494 public String includeDecoration(String template, String templateType) throws IOException
495 {
496 checkState();
497 try
498 {
499 return getDecoration(template, templateType).getAppRelativePath();
500 }
501 catch (Exception e)
502 {
503 PrintWriter directError = new PrintWriter(renderResponse.getWriter());
504 directError.write("Error occured process includeDecoration(): " + e.toString() + "\n\n");
505 e.printStackTrace(directError);
506 directError.close();
507 return null;
508 }
509 }
510
511 /***
512 * <p>
513 * Decorate and include fragment content.
514 * </p>
515 *
516 * @param f
517 * Fragment to include and decorate
518 * @throws Exception
519 * @return String path to the decorator.
520 */
521 public String decorateAndInclude(ContentFragment f) throws Exception
522 {
523
524
525
526 setCurrentFragment(f);
527 setCurrentLayout();
528
529
530 try
531 {
532 return decorateAndIncludePortlet(f);
533 }
534 catch (Exception e)
535 {
536 renderResponse.getWriter().write(e.toString());
537 return null;
538 }
539
540 }
541
542 /***
543 * <p>
544 * The decorator template itself is responsible for including the content of
545 * the target Fragment which is easily acheived like so: <br />
546 * in Velocity:
547 *
548 * <pre>
549 * <code>
550 * $jetspeed.include($jetspeed.currentFragment)
551 * </code>
552 * </pre>
553 *
554 * In JSP:
555 *
556 * <pre>
557 * <code>
558 *
559 * <%
560 * JetspeedPowerTool jetspeed = new JetspeedPowerTool(renderRequest, renderResponse, portletConfig);
561 * jetspeed.include(jetspeed.getCurrentFragment());
562 * %>
563 *
564 * </code>
565 * </pre>
566 *
567 *
568 * @param f
569 * Portlet fragment to "decorate"
570 * @throws Exception
571 */
572 protected String decorateAndIncludePortlet(ContentFragment f) throws Exception
573 {
574
575
576
577
578
579 String fragmentType = f.getType();
580 String decorator = f.getDecorator();
581 if (decorator == null)
582 {
583 decorator = getPage().getEffectiveDefaultDecorator(fragmentType);
584 }
585
586
587 TemplateDescriptor propsTemp = getTemplate(decorator + "/" + DECORATOR_TYPE + ".properties", fragmentType,
588 decorationLocator, decorationLocatorDescriptor);
589 if (propsTemp == null)
590 {
591 fragmentType = GENERIC_TEMPLATE_TYPE;
592 propsTemp = getTemplate(decorator + "/" + DECORATOR_TYPE + ".properties", fragmentType, decorationLocator,
593 decorationLocatorDescriptor);
594 }
595
596
597 Configuration decoConf = new PropertiesConfiguration(propsTemp.getAbsolutePath());
598 String ext = decoConf.getString("template.extension");
599 String decoratorPath = decorator + "/" + DECORATOR_TYPE + ext;
600 TemplateDescriptor template = null;
601 try
602 {
603 template = getDecoration(decoratorPath, fragmentType);
604 }
605 catch (TemplateLocatorException e)
606 {
607 String parent = decoConf.getString("extends");
608 if (parent != null)
609 {
610 template = getDecoration(parent + "/" + DECORATOR_TYPE + ext, fragmentType);
611 }
612 }
613
614 setAttribute(DECORATOR_ID_ATTR, decoConf.getString("id"));
615 setAttribute(ACTION_IMAGE_EXTENSION_ATTR, decoConf.getString("action.image.extension", ".gif"));
616 return template.getAppRelativePath();
617 }
618
619 /***
620 *
621 *
622 * @throws java.lang.IllegalStateException
623 * if the <code>PortletConfig</code>,
624 * <code>RenderRequest</code> or <code>RenderReponse</code>
625 * is null.
626 */
627 protected void checkState()
628 {
629 if (portletConfig == null || renderRequest == null || renderResponse == null)
630 {
631 throw new IllegalStateException("JetspeedPowerTool has not been properly initialized. " + ""
632 + "The JetspeedPowerTool generally only usuable during the rendering phase of "
633 + "internal portlet applications.");
634 }
635 }
636
637 protected TemplateDescriptor getTemplate(String path, String templateType, TemplateLocator locator,
638 LocatorDescriptor descriptor) throws TemplateLocatorException
639 {
640 checkState();
641 if (templateType == null)
642 {
643 templateType = GENERIC_TEMPLATE_TYPE;
644 }
645 try
646 {
647
648 descriptor.setName(path);
649 descriptor.setType(templateType);
650
651 TemplateDescriptor template = locator.locateTemplate(descriptor);
652
653 if (template == null)
654 {
655 Path pathObject = new Path(path);
656 if (pathObject.length() > 1)
657 {
658 template = getTemplate(pathObject.getSegment(1).toString(), templateType, locator, descriptor);
659 }
660 }
661 return template;
662 }
663 catch (TemplateLocatorException e)
664 {
665 log.error("Unable to locate template: " + path, e);
666
667 throw e;
668 }
669 }
670
671 /***
672 * <p>
673 * handleError
674 * </p>
675 *
676 * @param e
677 * @param msg
678 */
679 protected void handleError(Exception e, String msg, ContentFragment fragment)
680 {
681 log.error(msg, e);
682
683 Set exceptions = (Set) renderRequest.getAttribute(FRAGMENT_PROCESSING_ERROR_PREFIX + fragment.getId());
684 if (exceptions == null)
685 {
686 exceptions = new HashSet();
687 setAttribute(FRAGMENT_PROCESSING_ERROR_PREFIX + fragment.getId(), exceptions);
688 }
689 exceptions.add(e);
690
691 }
692
693 /***
694 * Gets the list of decorator actions for a window. Each window (on each
695 * page) has its own collection of actionAccess flags associated with it.
696 *
697 * @return A list of actions available to the current window, filtered by
698 * securty access and current state.
699 * @throws Exception
700 * @deprecated
701 */
702 public List getDecoratorActions()
703 {
704 return getCurrentFragment().getDecoration().getActions();
705 }
706
707 /***
708 * Gets the list of decorator actions for a page. Each layout fragment on a
709 * page has its own collection of actionAccess flags associated with it.
710 *
711 * @return A list of actions available to the current window, filtered by
712 * securty access and current state.
713 * @throws Exception
714 * @deprecated
715 */
716 public List getPageDecoratorActions() throws Exception
717 {
718 return getCurrentFragment().getDecoration().getActions();
719 }
720
721 /***
722 *
723 * <p>
724 * getTitle
725 * </p>
726 * Returns the appropriate for the title based on locale prferences
727 *
728 * @param entity
729 * @return
730 */
731 public String getTitle(PortletEntity entity, ContentFragment f)
732 {
733 String title = null;
734
735 if (f != null)
736 {
737 title = f.getTitle();
738 }
739
740 if (title == null)
741 {
742 try
743 {
744
745 return titleService.getDynamicTitle(windowAccess.getPortletWindow(f), getRequestContext().getRequest());
746 }
747 catch (Exception e)
748 {
749 log.error("Unable to reteive portlet title: " + e.getMessage(), e);
750 return "Title Error: " + e.getMessage();
751 }
752 }
753
754 return title;
755 }
756
757 /***
758 *
759 * <p>
760 * getTitle
761 * </p>
762 * Returns the appropriate for the title based on locale prferences
763 *
764 * @param entity
765 * @return
766 */
767 public String getTitle(PortletEntity entity)
768 {
769 try
770 {
771 return titleService.getDynamicTitle(windowAccess.getPortletWindow(getCurrentFragment()),
772 getRequestContext().getRequest());
773 }
774 catch (Exception e)
775 {
776 log.error("Unable to reteive portlet title: " + e.getMessage(), e);
777 return "Title Error: " + e.getMessage();
778 }
779
780 }
781
782 public Object getComponent(String name)
783 {
784 return Jetspeed.getComponentManager().getComponent(name);
785 }
786
787 public String getAbsoluteUrl(String relativePath)
788 {
789
790 if (relativePath != null && relativePath.indexOf("://") == -1 && relativePath.indexOf("mailto:") == -1)
791 {
792 HttpServletRequest request = getRequestContext().getRequest();
793 StringBuffer path = new StringBuffer();
794 if ( !getRequestContext().getPortalURL().isRelativeOnly() )
795 {
796 if (this.baseUrlAccess == null)
797 {
798 path.append(request.getScheme()).append("://").append(request.getServerName()).append(":").append(request.getServerPort());
799 }
800 else
801 {
802 path.append(baseUrlAccess.getServerScheme()).append("://").append(baseUrlAccess.getServerName()).append(":").append(baseUrlAccess.getServerPort());
803 }
804 }
805 return renderResponse.encodeURL(path.append(request.getContextPath()).append(request.getServletPath()).append(relativePath).toString());
806
807 }
808 else
809 {
810 return relativePath;
811 }
812 }
813
814 public Subject getSubject()
815 {
816 return requestContext.getSubject();
817 }
818
819 public boolean getLoggedOn()
820 {
821 Principal principal = requestContext.getRequest().getUserPrincipal();
822 return (principal != null);
823 }
824
825 public String getBasePath()
826 {
827 return getRequestContext().getPortalURL().getBasePath();
828 }
829
830 public String getPageBasePath()
831 {
832 return getRequestContext().getPortalURL().getPageBasePath();
833 }
834
835 public void setVelocityContext(Context velocityContext)
836 {
837 this.velocityContext = velocityContext;
838 }
839
840 /***
841 * Sets an attribute for use within your layout and decoration templates.
842 * The value is always stored within the current
843 * <code>javax.portlet.Renderrequest</code> and is also stored within the
844 * current <code>org.apache.velocity.Context</code> if it is available.
845 *
846 * @param name
847 * to store the attribute under.
848 * @param obj
849 * object to set.
850 */
851 protected void setAttribute(String name, Object object)
852 {
853 renderRequest.setAttribute(name, object);
854 if (velocityContext != null)
855 {
856 velocityContext.put(name, object);
857 }
858 }
859
860 public String renderPortletEntity(String entityId, String portletId)
861 {
862
863 RequestContext context = getRequestContext();
864
865 PortletAggregatorFragmentImpl fragment = new PortletAggregatorFragmentImpl(
866 entityId);
867 fragment.setType(Fragment.PORTLET);
868 fragment.setName(portletId);
869 ContentFragment contentFragment = new ContentFragmentImpl(fragment, new HashMap(), true);
870 renderer.renderNow(contentFragment, context);
871 return contentFragment.getRenderedContent();
872 }
873
874 }