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.portlets.layout;
18  
19  import java.io.IOException;
20  import java.util.HashMap;
21  import java.util.Locale;
22  import java.util.Map;
23  import java.util.StringTokenizer;
24  
25  import javax.portlet.ActionRequest;
26  import javax.portlet.ActionResponse;
27  import javax.portlet.PortletConfig;
28  import javax.portlet.PortletException;
29  import javax.portlet.PortletPreferences;
30  import javax.portlet.RenderRequest;
31  import javax.portlet.RenderResponse;
32  
33  import org.apache.commons.configuration.Configuration;
34  import org.apache.commons.configuration.ConfigurationException;
35  import org.apache.commons.configuration.PropertiesConfiguration;
36  import org.apache.commons.logging.Log;
37  import org.apache.commons.logging.LogFactory;
38  import org.apache.jetspeed.CommonPortletServices;
39  import org.apache.jetspeed.JetspeedActions;
40  import org.apache.jetspeed.PortalReservedParameters;
41  import org.apache.jetspeed.capabilities.CapabilityMap;
42  import org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent;
43  import org.apache.jetspeed.components.portletregistry.PortletRegistry;
44  import org.apache.jetspeed.container.window.PortletWindowAccessor;
45  import org.apache.jetspeed.layout.JetspeedPowerTool;
46  import org.apache.jetspeed.locator.LocatorDescriptor;
47  import org.apache.jetspeed.locator.TemplateDescriptor;
48  import org.apache.jetspeed.locator.TemplateLocator;
49  import org.apache.jetspeed.locator.TemplateLocatorException;
50  import org.apache.jetspeed.om.page.Fragment;
51  import org.apache.jetspeed.om.page.Page;
52  import org.apache.jetspeed.page.PageManager;
53  import org.apache.jetspeed.request.RequestContext;
54  import org.apache.jetspeed.velocity.JetspeedPowerToolFactory;
55  import org.apache.pluto.om.window.PortletWindow;
56  
57  /***
58   */
59  public class LayoutPortlet extends org.apache.portals.bridges.common.GenericServletPortlet
60  {
61      public static final String GENERIC_TEMPLATE_TYPE = "generic";
62  
63      public static final String FRAGMENT_PROCESSING_ERROR_PREFIX = "fragment.processing.error.";
64  
65      public static final String FRAGMENT_ATTR = "fragment";
66  
67      public static final String LAYOUT_ATTR = "layout";
68  
69      public static final String HIDDEN = "hidden";
70  
71      public static final String LAYOUT_TEMPLATE_TYPE = "layout";
72  
73      public static final String DECORATOR_TYPE = "decorator";
74      
75      public static final String PARAM_SOLO_PAGE = "SoloPage";
76      
77      
78      /*** Commons logging */
79      protected final static Log log = LogFactory.getLog(LayoutPortlet.class);
80      
81      protected PortletRegistry registry;
82      protected PageManager pageManager;
83      protected JetspeedPowerToolFactory jptFactory;
84      protected TemplateLocator templateLocator;
85      protected PortletEntityAccessComponent entityAccess;
86      protected PortletWindowAccessor windowAccess;
87      protected TemplateLocator decorationLocator;
88      
89      private Map layoutTemplatesCache = new HashMap();
90      public static final String DEFAULT_TEMPLATE_EXT = ".vm";
91      public static final String TEMPLATE_EXTENSION_KEY = "template.extension";
92      public static final String DEFAULT_TEMPLATE_TYPE = "velocity";
93      public static final String TEMPLATE_TYPE_KEY = "template.type";
94      
95      public void init( PortletConfig config ) throws PortletException
96      {
97          super.init(config);
98          
99          registry = (PortletRegistry)getPortletContext().getAttribute(CommonPortletServices.CPS_REGISTRY_COMPONENT);
100         if (null == registry)
101         {
102             throw new PortletException("Failed to find the Portlet Registry on portlet initialization");
103         }        
104         pageManager = (PageManager)getPortletContext().getAttribute(CommonPortletServices.CPS_PAGE_MANAGER_COMPONENT);
105         if (null == pageManager)
106         {
107             throw new PortletException("Failed to find the Page Manager on portlet initialization");
108         }        
109         jptFactory = (JetspeedPowerToolFactory)getPortletContext().getAttribute(CommonPortletServices.CPS_JETSPEED_POWERTOOL_FACTORY);
110         if (null == jptFactory)
111         {
112             throw new PortletException("Failed to find the JPT Factory on portlet initialization");
113         }        
114         
115         entityAccess = (PortletEntityAccessComponent) getPortletContext().getAttribute(CommonPortletServices.CPS_ENTITY_ACCESS_COMPONENT);
116         if (null == entityAccess)
117         {
118             throw new PortletException("Failed to find the Entity Access on portlet initialization");
119         }        
120         
121         windowAccess = (PortletWindowAccessor) getPortletContext().getAttribute(CommonPortletServices.CPS_WINDOW_ACCESS_COMPONENT);
122         if (null == windowAccess)
123         {
124             throw new PortletException("Failed to find the Window Access on portlet initialization");
125         }        
126         
127         templateLocator = (TemplateLocator) getPortletContext().getAttribute("TemplateLocator");
128         decorationLocator = (TemplateLocator) getPortletContext().getAttribute("DecorationLocator");
129     }
130 
131     public void doHelp( RenderRequest request, RenderResponse response ) throws PortletException, IOException
132     {
133         RequestContext context = getRequestContext(request);
134         response.setContentType(context.getMimeType());        
135         JetspeedPowerTool jpt = getJetspeedPowerTool(request);
136 
137         String absHelpPage = "";
138 
139         // request.setAttribute(PortalReservedParameters.PAGE_ATTRIBUTE, getPage(request));
140         // request.setAttribute("fragment", getFragment(request, false));        
141 
142         try
143         {
144             String helpPage = (String)request.getPortletSession().getAttribute(PortalReservedParameters.PAGE_LAYOUT_HELP);                       
145             if (helpPage == null)
146             {
147                 PortletPreferences prefs = request.getPreferences();
148                 helpPage = prefs.getValue(PARAM_HELP_PAGE, null);
149                 if (helpPage == null)
150                 {
151                     helpPage = this.getInitParameter(PARAM_HELP_PAGE);
152                     if (helpPage == null)
153                         helpPage = "columns";
154                 }
155                 request.getPortletSession().setAttribute(PortalReservedParameters.PAGE_LAYOUT_HELP, helpPage);
156             }
157 
158             String templateKey = helpPage + "/" + JetspeedPowerTool.LAYOUT_TEMPLATE_TYPE  + "-help";
159             CachedTemplate ct = (CachedTemplate)layoutTemplatesCache.get(templateKey);
160             if (ct == null)
161             {
162                 TemplateDescriptor template = null;
163                 Configuration props = getConfiguration(request, helpPage);
164                 String ext = (String) props.getString(TEMPLATE_EXTENSION_KEY);
165                 String path = helpPage + "/" + JetspeedPowerTool.LAYOUT_TEMPLATE_TYPE + "-help" + ext;                               
166                 template = jpt.getTemplate(path, JetspeedPowerTool.LAYOUT_TEMPLATE_TYPE);
167                 if (template == null)
168                 {
169                     String msg = "*** FAILED getTemplate:" + path;
170                     throw new TemplateLocatorException(msg);
171                 }
172                 else
173                 {
174                     synchronized(layoutTemplatesCache)
175                     {
176                         ct = new CachedTemplate(templateKey, template, props);
177                         layoutTemplatesCache.put(templateKey, ct);
178                     }                
179                 }
180             }
181                 
182             absHelpPage = ct.getTemplate().getAppRelativePath();            
183             log.debug("Path to help page for LayoutPortlet " + absHelpPage);
184             request.setAttribute(PARAM_VIEW_PAGE, absHelpPage);
185         }
186         catch (TemplateLocatorException e)
187         {
188             throw new PortletException("Unable to locate view page " + absHelpPage, e);
189         }
190         super.doView(request, response);
191 
192     }
193     
194     /***
195      * 
196      */
197     public void doView( RenderRequest request, RenderResponse response ) throws PortletException, IOException
198     {
199         RequestContext context = getRequestContext(request);
200         response.setContentType(context.getMimeType());        
201         PortletWindow window = context.getPortalURL().getNavigationalState().getMaximizedWindow();
202         boolean maximized = (window != null);
203         boolean solo = false;
204 
205         if (maximized)
206         {
207             request.setAttribute("layout", getMaximizedLayout(request));
208             solo = JetspeedActions.SOLO_STATE.equals(context.getPortalURL().getNavigationalState().getMappedState(window));
209             if ( solo )
210             {
211                 maximized = false;
212             }
213         }
214         else
215         {
216             request.setAttribute("layout", getFragment(request, false));
217         }
218         String viewPage = null;
219         String absViewPage = null;
220         try
221         {
222             JetspeedPowerTool jpt = getJetspeedPowerTool(request);
223             if (maximized)
224             {
225                 viewPage = (String)request.getPortletSession().getAttribute(PortalReservedParameters.PAGE_LAYOUT_MAX);                       
226                 if (viewPage == null)
227                 {
228                     PortletPreferences prefs = request.getPreferences();
229                     viewPage = prefs.getValue(PARAM_MAX_PAGE, null);
230                     if (viewPage == null)
231                     {
232                         viewPage = this.getInitParameter(PARAM_MAX_PAGE);
233                         if (viewPage == null)
234                             viewPage = "maximized";
235                     }
236                     request.getPortletSession().setAttribute(PortalReservedParameters.PAGE_LAYOUT_MAX, viewPage);
237                 }
238             }
239             else if (solo)
240             {
241                 viewPage = (String)request.getPortletSession().getAttribute(PortalReservedParameters.PAGE_LAYOUT_SOLO);                       
242                 if (viewPage == null)
243                 {
244                     PortletPreferences prefs = request.getPreferences();                
245                     viewPage = prefs.getValue(PARAM_SOLO_PAGE, null);
246                     if (viewPage == null)
247                     {
248                         viewPage = this.getInitParameter(PARAM_SOLO_PAGE);
249                         if (viewPage == null)
250                         {
251                             viewPage = "solo";
252                         }
253                     }
254                     request.getPortletSession().setAttribute(PortalReservedParameters.PAGE_LAYOUT_SOLO, viewPage);                    
255                 }
256             }
257             else
258             {
259                 viewPage = (String)request.getPortletSession().getAttribute(PortalReservedParameters.PAGE_LAYOUT_VIEW);                       
260                 if (viewPage == null)
261                 {
262                     PortletPreferences prefs = request.getPreferences();                                
263                     viewPage = prefs.getValue(PARAM_VIEW_PAGE, null);
264                     if (viewPage == null)
265                     {
266                         viewPage = this.getInitParameter(PARAM_VIEW_PAGE);
267                         if (viewPage == null)
268                             viewPage = "columns";
269                     }
270                     request.getPortletSession().setAttribute(PortalReservedParameters.PAGE_LAYOUT_VIEW, viewPage);                                        
271                 }
272             }
273             
274             String templateKey = viewPage + "/" + JetspeedPowerTool.LAYOUT_TEMPLATE_TYPE;
275             CachedTemplate ct = (CachedTemplate)layoutTemplatesCache.get(templateKey);
276             if (ct == null)
277             {
278                 TemplateDescriptor template = null;
279                 Configuration props = getConfiguration(request, viewPage);
280                 String ext = (String) props.getString(TEMPLATE_EXTENSION_KEY);
281                 String path = viewPage + "/" + JetspeedPowerTool.LAYOUT_TEMPLATE_TYPE + ext;
282                 
283                 template = jpt.getTemplate(path, JetspeedPowerTool.LAYOUT_TEMPLATE_TYPE);
284                 if (template == null)
285                 {
286                     String msg = "*** FAILED getTemplate:" + path;
287                     throw new TemplateLocatorException(msg);
288                 }
289                 else
290                 {
291                     synchronized(layoutTemplatesCache)
292                     {
293                         ct = new CachedTemplate(templateKey, template, props);
294                         layoutTemplatesCache.put(templateKey, ct);
295                     }
296                 
297                 }
298             }
299             absViewPage = ct.getTemplate().getAppRelativePath();
300             log.debug("Path to view page for LayoutPortlet " + absViewPage);
301             request.setAttribute(PARAM_VIEW_PAGE, absViewPage);
302         }
303         catch (TemplateLocatorException e)
304         {
305             throw new PortletException("Unable to locate view page " + absViewPage, e);
306         }
307         super.doView(request, response);
308 
309         request.removeAttribute(PortalReservedParameters.PAGE_ATTRIBUTE);
310         request.removeAttribute("fragment");
311         request.removeAttribute("layout");
312         request.removeAttribute("dispatcher");
313     }
314     
315     public void processAction(ActionRequest request, ActionResponse response)
316     throws PortletException, IOException
317     {
318         String page = request.getParameter("page");
319         String deleteFragmentId = request.getParameter("deleteId");
320         String portlets = request.getParameter("portlets");
321         if (deleteFragmentId != null && deleteFragmentId.length() > 0)
322         {
323             removeFragment(page, deleteFragmentId);
324         }
325         else if (portlets != null && portlets.length() > 0)
326         {
327             int count = 0;
328             StringTokenizer tokenizer = new StringTokenizer(portlets, ",");            
329             while (tokenizer.hasMoreTokens())
330             {
331                 String portlet = tokenizer.nextToken();
332                 try
333                 {
334                     if (portlet.startsWith("box_"))
335                     {
336                         portlet = portlet.substring("box_".length());                        
337                         addPortletToPage(page, portlet);
338                         count++;
339                     }
340                 }
341                 catch (Exception e)
342                 {
343                     log.error("failed to add portlet to page: " + portlet);
344                 }
345             }
346             
347         }       
348     }
349 
350     protected void removeFragment(String pageId, String fragmentId)
351     {
352         Page page = null;
353         try
354         {
355             page = pageManager.getPage(pageId);
356             
357         }
358         catch (Exception e)
359         {
360             log.error("failed to remove portlet " + fragmentId + " from page: " + pageId, e);
361         }
362         removeFragment(page,page.getRootFragment(), fragmentId);            
363     }
364     
365     protected void removeFragment(Page page, Fragment root, String fragmentId)
366     {
367         try
368         {
369             Fragment f = page.getFragmentById(fragmentId);
370             if ( f == null )
371             {
372                 // ignore no longer existing fragment error
373                 return;
374             }
375             root.getFragments().remove(f);
376             pageManager.updatePage(page);
377         }
378         catch (Exception e)
379         {
380             log.error("failed to remove portlet " + fragmentId + " from page: " + page, e);
381         }
382     }
383     
384     protected void addPortletToPage(String pageId, String portletId)
385     {
386         Page page = null;
387         try
388         {
389             page = pageManager.getContentPage(pageId);
390         }
391         catch (Exception e)
392         {
393             log.error("failed to add portlet " + portletId + " to page: " + pageId, e);
394         }
395         addPortletToPage(page, page.getRootFragment(), portletId);
396     }
397     
398     protected void addPortletToPage(Page page, Fragment root, String portletId)
399     {
400         try
401         {
402             Fragment fragment = pageManager.newFragment();
403             fragment.setType(Fragment.PORTLET);
404             fragment.setName(portletId);
405             
406             root.getFragments().add(fragment);
407             pageManager.updatePage(page);            
408         }
409         catch (Exception e)
410         {
411             log.error("failed to add portlet " + portletId + " to page: " + page, e);
412         }
413     }
414     
415     /***
416      * <p>
417      * initJetspeedPowerTool
418      * </p>
419      * 
420      * @param request
421      * @param response
422      * @return
423      * @throws PortletException
424      */
425     protected JetspeedPowerTool getJetspeedPowerTool( RenderRequest request ) throws PortletException
426     {
427         JetspeedPowerTool tool = (JetspeedPowerTool) request.getAttribute(PortalReservedParameters.JETSPEED_POWER_TOOL_REQ_ATTRIBUTE);
428         RequestContext requestContext = (RequestContext) request.getAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE);
429 
430         if (tool == null)
431         {
432 
433             try
434             {
435                 if (requestContext == null)
436                 {
437                     throw new IllegalStateException(
438                             "LayoutPortlet unable to handle request because there is no RequestContext in "
439                                     + "the HttpServletRequest.");
440                 }
441 
442                 tool = this.jptFactory.getJetspeedPowerTool(requestContext);
443                 request.setAttribute(PortalReservedParameters.JETSPEED_POWER_TOOL_REQ_ATTRIBUTE, tool);
444             }
445 
446             catch (Exception e1)
447             {
448                 throw new PortletException("Unable to init JetspeedPowerTool: " + e1.toString(), e1);
449             }
450         }
451         
452         return tool;
453     }
454     
455     /***
456      * 
457      * @param request
458      * @param maximized
459      * @return
460      */
461     protected Fragment getFragment( RenderRequest request, boolean maximized )
462     {
463         String attribute = (maximized)
464                 ? PortalReservedParameters.MAXIMIZED_FRAGMENT_ATTRIBUTE
465                 : PortalReservedParameters.FRAGMENT_ATTRIBUTE;
466         return (Fragment) request.getAttribute(attribute);       
467     }
468    
469     /***
470      * 
471      * @param request
472      * @return
473      */
474     protected Fragment getMaximizedLayout( RenderRequest request )
475     {
476         return (Fragment) request.getAttribute(PortalReservedParameters.MAXIMIZED_LAYOUT_ATTRIBUTE);
477     }
478     
479     /***
480      * 
481      * @param request
482      * @return
483      */
484     protected RequestContext getRequestContext( RenderRequest request )
485     {
486         RequestContext requestContext = (RequestContext) request
487                 .getAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE);
488         if (requestContext != null)
489         {
490             return requestContext;
491         }
492         else
493         {
494             throw new IllegalStateException(
495                     "getRequestContext() failed as it appears that no RenderRequest is available within the RenderRequest");
496         }
497     }
498 
499     /***
500      * <p>
501      * doEdit
502      * </p>
503      * 
504      * @see javax.portlet.GenericPortlet#doEdit(javax.portlet.RenderRequest,
505      *          javax.portlet.RenderResponse)
506      * @param request
507      * @param response
508      * @throws PortletException
509      * @throws IOException
510      */
511     public void doEdit( RenderRequest request, RenderResponse response ) throws PortletException, IOException
512     {
513         doView(request, response);
514     }
515     
516     /***
517      * 
518      * @param request
519      * @return
520      * @throws TemplateLocatorException
521      */
522     protected LocatorDescriptor getTemplateLocatorDescriptor(RenderRequest request) throws TemplateLocatorException
523     {
524         RequestContext requestContext = getRequestContext(request);
525         CapabilityMap capabilityMap = requestContext.getCapabilityMap();
526         Locale locale = requestContext.getLocale();
527 
528         LocatorDescriptor templateLocatorDescriptor = templateLocator.createLocatorDescriptor(null);
529         templateLocatorDescriptor.setMediaType(capabilityMap.getPreferredMediaType().getName());
530         templateLocatorDescriptor.setCountry(locale.getCountry());
531         templateLocatorDescriptor.setLanguage(locale.getLanguage());
532         return templateLocatorDescriptor;     
533     }
534     
535     
536     /***
537      * 
538      * @param request
539      * @return
540      * @throws TemplateLocatorException
541      */
542     protected LocatorDescriptor getDecoratorLocatorDescriptor(RenderRequest request) throws TemplateLocatorException
543     {
544         RequestContext requestContext = getRequestContext(request);
545         CapabilityMap capabilityMap = requestContext.getCapabilityMap();
546         Locale locale = requestContext.getLocale();
547   
548         LocatorDescriptor decorationLocatorDescriptor = decorationLocator.createLocatorDescriptor(null);
549         decorationLocatorDescriptor.setMediaType(capabilityMap.getPreferredMediaType().getName());
550         decorationLocatorDescriptor.setCountry(locale.getCountry());
551         decorationLocatorDescriptor.setLanguage(locale.getLanguage());
552         
553         return decorationLocatorDescriptor;
554     }
555     
556     /***
557      * 
558      * @param request
559      * @param fragment
560      * @param page
561      * @return
562      * @throws TemplateLocatorException
563      * @throws ConfigurationException
564      */
565     public String decorateAndInclude(RenderRequest request, Fragment fragment, Page page) throws TemplateLocatorException, ConfigurationException
566     {   
567         String fragmentType = fragment.getType();
568         String decorator = fragment.getDecorator();
569         LocatorDescriptor decorationLocatorDescriptor = getDecoratorLocatorDescriptor(request);
570         if (decorator == null)
571         {
572             decorator = page.getEffectiveDefaultDecorator(fragmentType);
573         }
574 
575         // get fragment properties for fragmentType or generic
576         TemplateDescriptor propsTemp = getTemplate(decorator + "/" + DECORATOR_TYPE + ".properties", fragmentType,
577                 decorationLocator, decorationLocatorDescriptor);
578         if (propsTemp == null)
579         {
580             fragmentType = GENERIC_TEMPLATE_TYPE;
581             propsTemp = getTemplate(decorator + "/" + DECORATOR_TYPE + ".properties", fragmentType, decorationLocator,
582                     decorationLocatorDescriptor);
583         }
584 
585         // get decorator template
586         Configuration decoConf = new PropertiesConfiguration(propsTemp.getAbsolutePath());
587         String ext = decoConf.getString("template.extension");
588         String decoratorPath = decorator + "/" + DECORATOR_TYPE + ext;
589         TemplateDescriptor template = null;
590         try
591         {
592             template = getDecoration(request, decoratorPath, fragmentType);
593         }
594         catch (TemplateLocatorException e)
595         {
596             String parent = decoConf.getString("extends");
597             if (parent != null)
598             {
599                 template = getDecoration(request, parent + "/" + DECORATOR_TYPE + ext, fragmentType);
600             }
601         }
602 
603         return  template.getAppRelativePath();
604     }
605     
606     /***
607      * 
608      * @param request
609      * @param path
610      * @param templateType
611      * @return
612      * @throws TemplateLocatorException
613      */
614     protected TemplateDescriptor getDecoration( RenderRequest request, String path, String templateType ) throws TemplateLocatorException
615     {        
616         return getTemplate(path, templateType, decorationLocator, getDecoratorLocatorDescriptor(request));
617     }
618     
619     /***
620      * 
621      * @param path
622      * @param templateType
623      * @param locator
624      * @param descriptor
625      * @return
626      * @throws TemplateLocatorException
627      */
628     protected TemplateDescriptor getTemplate( String path, String templateType, TemplateLocator locator,
629             LocatorDescriptor descriptor ) throws TemplateLocatorException
630     {
631         
632         if (templateType == null)
633         {
634             templateType = GENERIC_TEMPLATE_TYPE;
635         }
636         try
637         {
638 
639             descriptor.setName(path);
640             descriptor.setType(templateType);
641 
642             TemplateDescriptor template = locator.locateTemplate(descriptor);
643             return template;
644         }
645         catch (TemplateLocatorException e)
646         {
647             log.error("Unable to locate template: " + path, e);
648             throw e;
649         }
650     }
651 
652     /***
653      * Gets the configuration (layout.properties) object for the decoration.
654      * @param name Name of the Decoration.
655      * @return <code>java.util.Properties</code> representing the configuration
656      * object.
657      */
658     protected Configuration getConfiguration( RenderRequest request, String name )
659     {
660         Configuration props = null;
661         JetspeedPowerTool jpt = null;
662         String templatePropertiesPath = null;
663         String key = name;
664         try
665         {
666             jpt = getJetspeedPowerTool(request);
667             templatePropertiesPath = jpt.getTemplate(name + "/" + JetspeedPowerTool.LAYOUT_TEMPLATE_TYPE + ".properties",
668                     JetspeedPowerTool.LAYOUT_TEMPLATE_TYPE).getAbsolutePath();
669         } 
670         catch (PortletException e)
671         {
672             log.warn("Could not acquire JetspeedPowerTool from request",e);
673         }
674         catch (TemplateLocatorException e)
675         {
676             log.warn("Could not find templatePorpertiesPath",e);
677         }
678         catch (Exception e)
679         {
680             log.warn("Could not determine Layout template properties file",e);
681         }
682         // if no path then set name to "default"
683         if (null == templatePropertiesPath)
684         {
685             key = "default";
686         }
687         else
688         {
689             key = templatePropertiesPath;
690         }
691         if (log.isDebugEnabled())
692         {
693             log.debug(
694                     "Template descriptor path:<" + templatePropertiesPath + ">"
695             );
696         }
697 
698         // load Decoration.CONFIG_FILE_NAME (layout.properties)
699         try
700         {
701             props = new PropertiesConfiguration(templatePropertiesPath);
702             if (log.isDebugEnabled())
703                 log.debug("Successfully read in: <" + templatePropertiesPath + "> ");
704         } 
705         catch (Exception e)
706         {
707             props = new PropertiesConfiguration();
708             log.warn( "Could not locate the " + templatePropertiesPath + " file for layout template \"" + name + "\".  This layout template may not exist.",e );
709             props.setProperty( "id", name );
710             props.setProperty( TEMPLATE_TYPE_KEY, DEFAULT_TEMPLATE_TYPE );
711             props.setProperty( TEMPLATE_EXTENSION_KEY, DEFAULT_TEMPLATE_EXT);
712         }
713         finally
714         {
715             String templateIdPropVal = (String) props.getProperty( "id" );
716             String templateNamePropVal = (String) props.getProperty( TEMPLATE_TYPE_KEY );
717             String templateExtPropVal = (String) props.getProperty(TEMPLATE_EXTENSION_KEY);
718             
719             if ( templateIdPropVal == null )
720             {
721                 templateIdPropVal = name;
722                 props.setProperty( "id", templateIdPropVal );
723             }
724             
725             if ( templateNamePropVal == null )
726             {
727                 props.setProperty( TEMPLATE_TYPE_KEY, DEFAULT_TEMPLATE_TYPE );
728             }
729             if ( templateExtPropVal == null )
730             {
731                 props.setProperty( TEMPLATE_EXTENSION_KEY, DEFAULT_TEMPLATE_EXT );
732             }
733         }
734 
735         if (log.isDebugEnabled())
736         {
737             log.debug("Template layout.properties extension is:<" + props.getString(TEMPLATE_EXTENSION_KEY));
738         }
739         return props;
740     }
741 
742     class CachedTemplate
743     {
744         private String key;
745         private TemplateDescriptor template;
746         private Configuration config;
747         
748         public CachedTemplate(String key, TemplateDescriptor template, Configuration config)
749         {
750             this.key = key;
751             this.template = template;
752             this.config = config;
753         }
754 
755         
756         public Configuration getConfig()
757         {
758             return config;
759         }
760 
761         
762         public String getKey()
763         {
764             return key;
765         }
766 
767         
768         public TemplateDescriptor getTemplate()
769         {
770             return template;
771         }
772     }
773 }