View Javadoc

1   /* 
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
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             // BasePortalURL is optional: ignore (org.springframework.beans.factory.NoSuchBeanDefinitionException)
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         // By using null, we create a re-useable locator
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         // return (Page)
322         // renderRequest.getAttribute(PortalReservedParameters.PAGE_ATTRIBUTE_KEY);
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         // This API hits the DB: PortletEntity portletEntity = entityAccess.getPortletEntityForFragment(f);
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         // makes sure that any previous content has been written to
524         // preserve natural HTML rendering order
525 
526         setCurrentFragment(f);
527         setCurrentLayout();
528 
529         // include decorated layout or portlet fragment
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      *              &lt;% 
560      *               JetspeedPowerTool jetspeed = new JetspeedPowerTool(renderRequest, renderResponse, portletConfig);
561      *               jetspeed.include(jetspeed.getCurrentFragment());
562      *              %&gt;
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         // make sure that any previous content has been written to
575         // preserve natural HTML rendering order
576 
577         // get fragment decorator; fallback to the default decorator
578         // if the current fragment is not specifically decorated
579         String fragmentType = f.getType();
580         String decorator = f.getDecorator();
581         if (decorator == null)
582         {
583             decorator = getPage().getEffectiveDefaultDecorator(fragmentType);
584         }
585 
586         // get fragment properties for fragmentType or generic
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         // get decorator template
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             // Check for defaults above the currently specified root
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 //            System.out.println("Unable to locate template: " + path);
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         // only rewrite a non-absolute url
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 }