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.aggregator.impl;
18  
19  import java.io.IOException;
20  import java.util.Iterator;
21  import java.util.Map;
22  import java.util.HashMap;
23  import java.util.List;
24  import java.util.ArrayList;
25  import java.util.Collections;
26  
27  import javax.portlet.Portlet;
28  
29  import org.apache.commons.logging.Log;
30  import org.apache.commons.logging.LogFactory;
31  
32  import org.apache.jetspeed.aggregator.FailedToRenderFragmentException;
33  import org.apache.jetspeed.aggregator.PageAggregator;
34  import org.apache.jetspeed.container.state.NavigationalState;
35  import org.apache.jetspeed.container.url.BasePortalURL;
36  import org.apache.jetspeed.container.window.PortletWindowAccessor;
37  import org.apache.jetspeed.decoration.DecorationFactory;
38  import org.apache.jetspeed.exception.JetspeedException;
39  import org.apache.jetspeed.factory.PortletFactory;
40  import org.apache.jetspeed.headerresource.HeaderResource;
41  import org.apache.jetspeed.headerresource.HeaderResourceFactory;
42  import org.apache.jetspeed.headerresource.HeaderResourceLib;
43  import org.apache.jetspeed.om.common.portlet.PortletApplication;
44  import org.apache.jetspeed.om.page.ContentFragment;
45  import org.apache.jetspeed.om.page.ContentPage;
46  import org.apache.jetspeed.portlet.PortletHeaderRequest;
47  import org.apache.jetspeed.portlet.PortletHeaderResponse;
48  import org.apache.jetspeed.portlet.SupportsHeaderPhase;
49  import org.apache.jetspeed.request.RequestContext;
50  import org.apache.jetspeed.PortalReservedParameters;
51  import org.apache.pluto.om.portlet.PortletDefinition;
52  import org.apache.pluto.om.window.PortletWindow;
53  
54  /***
55   * HeaderAggregator builds the content required to render a page of portlets.
56   * 
57   * @author <a href="mailto:raphael@apache.org">Rapha?l Luta </a>
58   * @author <a href="mailto:taylor@apache.org">David Sean Taylor </a>
59   * @author <a href="mailto:smilek@apache.org">Steve Milek</a>
60   * @version $Id: HeaderAggregatorImpl.java 359125 2005-12-26 23:16:39Z rwatler $
61   */
62  public class HeaderAggregatorImpl implements PageAggregator
63  {
64      protected final static Log log = LogFactory.getLog( HeaderAggregatorImpl.class );
65      protected final static String EOL = "\r\n";   // html eol
66  
67      private PortletFactory factory;
68      private PortletWindowAccessor windowAccessor;
69      private HeaderResourceFactory headerResourceFactory;
70      private DecorationFactory decorationFactory;
71      
72      private boolean isDesktop;
73      
74      private Map headerConfiguration;
75      private Map headerResourceRegistry;
76      private Map headerDynamicConfigurationDefault;
77      private Map headerNamedResourcesDefault;
78      private Map headerNamedResourcesAddedFragmentsDefault;
79      
80      /*** base portal URL to override default URL server info from servlet */
81      private BasePortalURL baseUrlAccess = null;
82      
83      
84      public HeaderAggregatorImpl( PortletFactory factory,
85                                   PortletWindowAccessor windowAccessor,
86                                   HeaderResourceFactory headerResourceFactory,
87                                   boolean isDesktop,
88                                   Map headerConfiguration,
89                                   Map headerResourceRegistry,
90                                   DecorationFactory decorationFactory )
91      {
92          this( factory, windowAccessor, headerResourceFactory, isDesktop, headerConfiguration, headerResourceRegistry, decorationFactory, null );
93      }
94      
95      public HeaderAggregatorImpl( PortletFactory factory,
96                                   PortletWindowAccessor windowAccessor,
97                                   HeaderResourceFactory headerResourceFactory,
98                                   boolean isDesktop,
99                                   Map headerConfiguration,
100                                  Map headerResourceRegistry,
101                                  DecorationFactory decorationFactory,
102                                  BasePortalURL baseUrlAccess )
103     {
104         this.factory = factory;
105         this.windowAccessor = windowAccessor;
106         this.headerResourceFactory = headerResourceFactory;
107         this.isDesktop = isDesktop;
108         this.baseUrlAccess = baseUrlAccess;
109         this.decorationFactory = decorationFactory;
110         initializeHeaderConfiguration( headerConfiguration, headerResourceRegistry );   
111     }
112     
113     /***
114      * Initialize header configuration, making immutable copies of the data structures and 
115      * compiling as much finished static header content as possible (to minimize repetitive work per request)
116      */
117     private void initializeHeaderConfiguration( Map headerConfigArg, Map headerRsrcRegistryArg )
118     {
119         this.headerConfiguration = null;
120         this.headerResourceRegistry = null;
121         this.headerDynamicConfigurationDefault = null;
122         this.headerNamedResourcesDefault = null;
123         this.headerNamedResourcesAddedFragmentsDefault = null;
124         
125         if ( headerConfigArg != null && headerConfigArg.size() > 0 )
126         {
127             // attempt to make safe immutable copy of headerConfigArg
128             HashMap headerConfig = new HashMap();
129             Iterator headerConfigEntryIter = headerConfigArg.entrySet().iterator();
130             while ( headerConfigEntryIter.hasNext() )
131             {
132                 Map.Entry headerConfigEntry = (Map.Entry)headerConfigEntryIter.next();
133                 Object headerConfigKey = headerConfigEntry.getKey();
134                 Object headerConfigVal = headerConfigEntry.getValue();
135                 if ( headerConfigVal instanceof Map )
136                 {
137                     headerConfig.put( headerConfigKey, Collections.unmodifiableMap( new HashMap( (Map)headerConfigVal ) ) );
138                 }
139                 else if ( headerConfigVal instanceof List )
140                 {
141                     headerConfig.put( headerConfigKey, Collections.unmodifiableList( new ArrayList( (List)headerConfigVal ) ) );
142                 }
143                 else
144                 {
145                     headerConfig.put( headerConfigKey, headerConfigVal );
146                 }
147             }
148             this.headerConfiguration = Collections.unmodifiableMap( headerConfig );
149             
150             // make modifiable copy of headerRsrcRegistryArg - is made immutable at end of initializeHeaderConfiguration()
151             Map headerRsrcRegistry = null;
152             if ( headerRsrcRegistryArg != null && headerRsrcRegistryArg.size() > 0 )
153             {
154                 headerRsrcRegistry = new HashMap( headerRsrcRegistryArg );
155                 // leave modifiable during initializeHeaderConfigurationDefaults() protocol
156                 //    (so that entries can be removed - possibly leading to an empty map which will save a bunch of gratuitous lookups)
157             }
158             else
159             {
160                 headerRsrcRegistry = new HashMap();
161             }
162             this.headerResourceRegistry = headerRsrcRegistry;   
163 
164             HashMap namedResourcesDefault = new HashMap();
165             HashMap namedResourcesAddedFragmentsDefault = new HashMap();
166             
167             Map dynamicConfigurationDefault = initializeHeaderConfigurationDefaults( namedResourcesDefault, namedResourcesAddedFragmentsDefault );
168             if ( dynamicConfigurationDefault != null )
169                 this.headerDynamicConfigurationDefault = Collections.unmodifiableMap( dynamicConfigurationDefault );
170             
171             this.headerNamedResourcesDefault = Collections.unmodifiableMap( namedResourcesDefault );
172             this.headerNamedResourcesAddedFragmentsDefault = Collections.unmodifiableMap( namedResourcesAddedFragmentsDefault );
173             
174             this.headerResourceRegistry = null;
175             if ( headerRsrcRegistry != null && headerRsrcRegistry.size() > 0 )
176             {
177                 this.headerResourceRegistry = Collections.unmodifiableMap( headerRsrcRegistry );
178             }
179         }
180     }
181 
182     /***
183      * Initialize dynamic-header-configuration and call initializeHeaderConfigurationEntryDefaults() for
184      * each key in headerConfiguration Map, allowing for each to add resources and settings to:
185      * headerNamedResourcesDefault, headerNamedResourcesAddedFragmentsDefault and headerDynamicConfigurationDefault
186      * 
187      * If no specific handler is defined for a headerConfiguration key, the entry is copied to headerDynamicConfigurationDefault
188      * otherwise the handler is responsible for adding information to headerDynamicConfigurationDefault
189      * 
190      * headerConfiguration handlers are currently defined for the headerConfiguration keys:
191      *    "header.order"         - HeaderResource.HEADER_CONFIG_ORDER
192      *    "header.types"         - HeaderResource.HEADER_CONFIG_TYPES
193      *    "header.requiredflag"  - HeaderResource.HEADER_CONFIG_REQUIREDFLAG
194      *    "dojo"                 - HeaderResource.HEADER_CONFIG_DOJO
195      *    "desktop"              - HeaderResource.HEADER_CONFIG_DESKTOP
196      */
197     protected Map initializeHeaderConfigurationDefaults( HashMap namedResourcesDefault, HashMap namedResourcesAddedFragmentsDefault )
198     {
199         if ( this.headerConfiguration == null )
200         {
201             return null;
202         }
203         
204         HashMap headerDynamicConfigurationDefault = new HashMap();
205         
206         initializeHeaderOrderConfigurationDefaults( namedResourcesDefault, namedResourcesAddedFragmentsDefault, headerDynamicConfigurationDefault );
207 
208         // setting header.basetag type - without adding it to order
209         setNamedHeaderResourceProperties( HeaderResource.HEADER_SECTION_BASE_TAG, HeaderResource.HEADER_TYPE_BASE_TAG, null, headerDynamicConfigurationDefault );
210         
211         Iterator hConfigEntryIter = this.headerConfiguration.entrySet().iterator();
212         while ( hConfigEntryIter.hasNext() )
213         {
214             Map.Entry hConfigEntry = (Map.Entry)hConfigEntryIter.next();
215             Object hConfigKey = hConfigEntry.getKey();
216             Object hConfigVal = hConfigEntry.getValue();
217             
218             if ( ! initializeHeaderConfigurationEntryDefaults( hConfigKey, hConfigVal, namedResourcesDefault, namedResourcesAddedFragmentsDefault, headerDynamicConfigurationDefault ) )
219             {
220                 if ( hConfigVal instanceof Map )
221                 {
222                     headerDynamicConfigurationDefault.put( hConfigKey, Collections.unmodifiableMap( new HashMap( (Map)hConfigVal ) ) );
223                 }
224                 else if ( hConfigVal instanceof List )
225                 {
226                     headerDynamicConfigurationDefault.put( hConfigKey, Collections.unmodifiableList( new ArrayList( (List)hConfigVal ) ) );
227                 }
228                 else
229                 {
230                     headerDynamicConfigurationDefault.put( hConfigKey, hConfigVal );
231                 }
232             }
233         }
234         initializeMissingHeaderConfigurationEntryDefaults( namedResourcesDefault, namedResourcesAddedFragmentsDefault, headerDynamicConfigurationDefault );
235         
236         postinitializeHeaderOrderConfigurationDefaults( headerDynamicConfigurationDefault );
237         
238         return headerDynamicConfigurationDefault;
239     }
240     
241     protected void initializeHeaderOrderConfigurationDefaults( HashMap namedResourcesDefault, HashMap namedResourcesAddedFragmentsDefault, HashMap headerDynamicConfigurationDefault )
242     {
243         if ( this.headerConfiguration != null )
244         {
245             List headerOrderConfigList = (List)this.headerConfiguration.get( HeaderResource.HEADER_CONFIG_ORDER );
246             if ( headerOrderConfigList != null && headerOrderConfigList.size() > 0 )
247             {
248                 ArrayList headerOrderList = new ArrayList();
249                 Map headerNames = new HashMap();
250                 Iterator headerOrderListIter = headerOrderConfigList.iterator();
251                 while ( headerOrderListIter.hasNext() )
252                 {
253                     Object headerNameObj = headerOrderListIter.next();
254                     if ( headerNameObj != null )
255                     {
256                         String headerName = headerNameObj.toString();
257                         if ( headerName != null && headerName.length() > 0 )
258                         {
259                             headerOrderList.add( headerName );
260                             headerNames.put( headerName, Boolean.TRUE );
261                         }
262                     }
263                 }
264                 // add modifiable structures at this point - so that later initialization steps can manipulate the defaults
265                 // needs to be made unmodifiable at end of processing by calling postinitializeHeaderOrderConfigurationDefaults()
266                 headerDynamicConfigurationDefault.put( HeaderResource.HEADER_CONFIG_ORDER, headerOrderList );
267                 headerDynamicConfigurationDefault.put( HeaderResource.HEADER_INTERNAL_INCLUDED_NAMES, headerNames );
268             }
269             
270             Map headerTypes = null;
271             Map headerTypesConfig = (Map)this.headerConfiguration.get( HeaderResource.HEADER_CONFIG_TYPES );
272             if ( headerTypesConfig != null && headerTypesConfig.size() > 0 )
273             {
274                 headerTypes = new HashMap();
275                 Iterator headerTypesConfigIter = headerTypesConfig.entrySet().iterator();
276                 while ( headerTypesConfigIter.hasNext() )
277                 {
278                     Map.Entry headerTypeEntry = (Map.Entry)headerTypesConfigIter.next();
279                     Object headerNameObj = headerTypeEntry.getKey();
280                     Object headerTypeObj = headerTypeEntry.getValue();
281                     if ( headerNameObj != null && headerTypeObj != null )
282                     {
283                         String headerName = headerNameObj.toString();
284                         int headerTypeId = HeaderResourceLib.getHeaderTypeId( headerTypeObj.toString() );
285                         if ( headerName != null )
286                         {
287                             if ( headerTypeId >= 0 )
288                             {
289                                 headerTypes.put( headerName, new Object[] { new Integer( headerTypeId ), null } );
290                             }
291                             else
292                             {
293                                 log.error( "HeaderAggregatorImpl.initializeHeaderOrderConfigurationDefaults() ignoring specification of unknown header section type; header-section-name=" + headerName + " header-section-type=" + headerTypeObj.toString() );
294                             }
295                         }
296                     }
297                 }
298             }
299             
300             Map headerRequiredFlagConfig = (Map)this.headerConfiguration.get( HeaderResource.HEADER_CONFIG_REQUIREDFLAG );
301             if ( headerRequiredFlagConfig != null && headerRequiredFlagConfig.size() > 0 )
302             {
303                 if ( headerTypes == null )
304                 {
305                     headerTypes = new HashMap();
306                 }
307                 Iterator headerRequiredFlagConfigIter = headerRequiredFlagConfig.entrySet().iterator();
308                 while ( headerRequiredFlagConfigIter.hasNext() )
309                 {
310                     Map.Entry headerRequiredFlagEntry = (Map.Entry)headerRequiredFlagConfigIter.next();
311                     Object headerNameObj = headerRequiredFlagEntry.getKey();
312                     Object headerReqFlagObj = headerRequiredFlagEntry.getValue();
313                     if ( headerNameObj != null && headerReqFlagObj != null )
314                     {
315                         String headerName = headerNameObj.toString();
316                         String headerReqFlag = headerReqFlagObj.toString();
317                         if ( headerName != null && headerName.length() > 0 && headerReqFlag != null )
318                         {
319                             Object[] headerTypePair = (Object[])headerTypes.get( headerName );
320                             if ( headerTypePair != null )
321                             {
322                                 headerTypePair[1] = headerReqFlag;
323                             }
324                             else
325                             {
326                                 headerTypePair = new Object[] { null, headerReqFlag };
327                                 headerTypes.put( headerName, headerTypePair );
328                             }
329                         }
330                     }
331                 }
332             }
333             if ( headerTypes != null && headerTypes.size() > 0 )
334             {
335                 headerDynamicConfigurationDefault.put( HeaderResource.HEADER_CONFIG_TYPES, headerTypes );
336             }
337         }
338     }
339     protected void postinitializeHeaderOrderConfigurationDefaults( HashMap headerDynamicConfigurationDefault )
340     {
341         if ( headerDynamicConfigurationDefault != null )
342         {
343             Map headerNames = (Map)headerDynamicConfigurationDefault.get( HeaderResource.HEADER_INTERNAL_INCLUDED_NAMES );
344             if ( headerNames != null )
345             {
346                 headerDynamicConfigurationDefault.put( HeaderResource.HEADER_INTERNAL_INCLUDED_NAMES, Collections.unmodifiableMap( headerNames ) );
347             }
348             Map headerTypes = (Map)headerDynamicConfigurationDefault.get( HeaderResource.HEADER_CONFIG_TYPES );
349             if ( headerTypes != null )
350             {
351                 headerDynamicConfigurationDefault.put( HeaderResource.HEADER_CONFIG_TYPES, Collections.unmodifiableMap( headerTypes ) );
352             }
353             List headerOrderList = (List)headerDynamicConfigurationDefault.get( HeaderResource.HEADER_CONFIG_ORDER );
354             if ( headerOrderList != null )
355             {
356                 headerDynamicConfigurationDefault.put( HeaderResource.HEADER_CONFIG_ORDER, Collections.unmodifiableList( headerOrderList ) );
357             }
358         }
359     }
360     
361     /***
362      * Intended as derived class hook into header configuration process
363      * 
364      * @return true if headerConfigKey has been processed or false if default processing should occur
365      */
366     protected boolean initializeHeaderConfigurationEntryDefaults( Object headerConfigKey, Object headerConfigValue, HashMap namedResourcesDefault, HashMap namedResourcesAddedFragmentsDefault, HashMap headerDynamicConfigurationDefault )
367     {
368         if ( headerConfigKey.equals( HeaderResource.HEADER_CONFIG_ORDER ) || headerConfigKey.equals( HeaderResource.HEADER_CONFIG_TYPES ) || headerConfigKey.equals( HeaderResource.HEADER_CONFIG_REQUIREDFLAG ) )
369         {
370             // do nothing - processed earlier with call to initializeHeaderOrderConfigurationDefaults()
371             return true;
372         }
373         else if ( headerConfigKey.equals( HeaderResource.HEADER_CONFIG_DOJO ) )
374         {
375             initializeDojoHeaderConfigurationDefaults( (Map)headerConfigValue, namedResourcesDefault, namedResourcesAddedFragmentsDefault, headerDynamicConfigurationDefault );
376             return true;
377         }
378         else if ( headerConfigKey.equals( HeaderResource.HEADER_CONFIG_DESKTOP ) )
379         {
380             initializeDesktopHeaderConfigurationDefaults( (Map)headerConfigValue, namedResourcesDefault, namedResourcesAddedFragmentsDefault, headerDynamicConfigurationDefault );
381             return true;
382         }
383         return false;
384     }
385     
386     protected void initializeMissingHeaderConfigurationEntryDefaults( HashMap namedResourcesDefault, HashMap namedResourcesAddedFragmentsDefault, HashMap headerDynamicConfigurationDefault )
387     {
388         if ( isDesktop() )
389         {
390             if ( this.headerConfiguration.get( HeaderResource.HEADER_CONFIG_DOJO ) == null )
391             {
392                 initializeDojoHeaderConfigurationDefaults( null, namedResourcesDefault, namedResourcesAddedFragmentsDefault, headerDynamicConfigurationDefault );
393             }
394             if ( this.headerConfiguration.get( HeaderResource.HEADER_CONFIG_DESKTOP ) == null )
395             {
396                 initializeDesktopHeaderConfigurationDefaults( null, namedResourcesDefault, namedResourcesAddedFragmentsDefault, headerDynamicConfigurationDefault );
397             }
398         }
399     }
400     
401     protected void registerAndOrderNamedHeaderResource( String headerName, String headerType, String headerReqFlag, Map headerDynamicConfigurationDefault )
402     {
403         orderNamedHeaderResource( headerName, headerDynamicConfigurationDefault );
404         setNamedHeaderResourceProperties( headerName, headerType, headerReqFlag, headerDynamicConfigurationDefault );
405     }
406     
407     protected void orderNamedHeaderResource( String headerName, Map headerDynamicConfigurationDefault )
408     {
409         if ( headerName != null )
410         {
411             Map headerNames = (Map)headerDynamicConfigurationDefault.get( HeaderResource.HEADER_INTERNAL_INCLUDED_NAMES );
412             if ( headerNames == null )
413             {
414                 headerNames = new HashMap();
415                 headerDynamicConfigurationDefault.put( HeaderResource.HEADER_INTERNAL_INCLUDED_NAMES, headerNames );
416             }
417             
418             Object headerNamesVal = headerNames.get( headerName );
419             if ( headerNamesVal == null )
420             {
421                 List headerOrderList = (List)headerDynamicConfigurationDefault.get( HeaderResource.HEADER_CONFIG_ORDER );
422                 if ( headerOrderList == null )
423                 {
424                     headerOrderList = new ArrayList();
425                     headerDynamicConfigurationDefault.put( HeaderResource.HEADER_CONFIG_ORDER, headerOrderList );
426                 }
427                 
428                 headerOrderList.add( headerName );
429                 headerNames.put( headerName, Boolean.TRUE );
430             }
431         }
432     }
433     
434     protected void setNamedHeaderResourceProperties( String headerName, String headerType, String headerReqFlag, Map headerDynamicConfigurationDefault )
435     {
436         if ( headerName != null )
437         {
438             int headerTypeId = HeaderResourceLib.getHeaderTypeId( headerType );
439             
440             boolean headerRefFlagSpecified = ( headerReqFlag != null && headerReqFlag.length() > 0 );
441             if ( headerTypeId < 0 && ! headerRefFlagSpecified )
442             {
443                 log.error( "HeaderAggregatorImpl.registerAndOrderNamedHeaderResource() ignoring specification of unknown header section type; header-section-name=" + headerName + " header-section-type=" + headerType );
444             }
445             
446             if ( ( headerTypeId >= 0 ) || headerRefFlagSpecified )
447             {
448                 Map headerTypes = (Map)headerDynamicConfigurationDefault.get( HeaderResource.HEADER_CONFIG_TYPES );
449                 if ( headerTypes == null )
450                 {
451                     headerTypes = new HashMap();
452                     headerDynamicConfigurationDefault.put( HeaderResource.HEADER_CONFIG_TYPES, headerTypes );
453                 }
454                 
455                 Object[] headerTypePair = (Object[])headerTypes.get( headerName );
456                 if ( headerTypePair == null )
457                 {
458                     headerTypePair = new Object[] { null, null };
459                     headerTypes.put( headerName, headerTypePair );
460                 }
461                 if ( headerTypePair[0] == null && headerTypeId >= 0 )
462                 {   // change only if value from configuration is null
463                     headerTypePair[0] = new Integer( headerTypeId );
464                 }
465                 if ( headerTypePair[1] == null && headerReqFlag != null && headerReqFlag.length() > 0 )
466                 {   // change only if value from configuration is null
467                     headerTypePair[1] = headerReqFlag;
468                 }
469             }
470         }
471     }
472     
473     protected boolean canAddHeaderNamedResourceFragment( String headerFragmentName, HashMap namedResourcesAddedFragmentsDefault, String[] registryContent )
474     {
475         if ( headerFragmentName != null && ! namedResourcesAddedFragmentsDefault.containsKey( headerFragmentName ) )
476         {
477             namedResourcesAddedFragmentsDefault.put( headerFragmentName, Boolean.TRUE );
478             if ( registryContent != null )
479             {
480                 String registryContentVal = (String)this.headerResourceRegistry.get( headerFragmentName );
481                 registryContent[0] = registryContentVal;
482                 if ( registryContentVal != null )
483                 {
484                     this.headerResourceRegistry.remove( headerFragmentName );
485                 }
486             }
487             return true;
488         }
489         if ( registryContent != null )
490         {
491             registryContent[0] = null;
492         }
493         return false;
494     }
495         
496     protected void initializeDesktopHeaderConfigurationDefaults( Map desktopConfigMap, HashMap namedResourcesDefault, HashMap namedResourcesAddedFragmentsDefault, HashMap headerDynamicConfigurationDefault )
497     {
498         if ( desktopConfigMap == null )
499         {
500             desktopConfigMap = new HashMap();
501         }
502         
503         StringBuffer desktopDojoConfigContent = new StringBuffer();
504         
505         String layoutDecorationDefaultName = HeaderResource.HEADER_CONFIG_DESKTOP_LAYOUT_DECORATION_DEFAULT;
506         String layoutDecoration = (String)desktopConfigMap.get( layoutDecorationDefaultName );
507         if ( layoutDecoration != null && layoutDecoration.length() > 0 )
508         {
509             decorationFactory.setDefaultDesktopLayoutDecoration( layoutDecoration );
510         }
511         
512         String portletDecorationDefaultName = HeaderResource.HEADER_CONFIG_DESKTOP_PORTLET_DECORATION_DEFAULT;
513         String portletDecoration = (String)desktopConfigMap.get( portletDecorationDefaultName );
514         if ( portletDecoration == null || portletDecoration.length() == 0 )
515         {
516             portletDecoration = decorationFactory.getDefaultDesktopPortletDecoration();
517         }
518         if ( portletDecoration != null && portletDecoration.length() > 0 )
519         {
520             if ( canAddHeaderNamedResourceFragment( portletDecorationDefaultName, namedResourcesAddedFragmentsDefault, null ) )
521             {
522                 desktopDojoConfigContent.append( "    " ).append( HeaderResource.HEADER_INTERNAL_DOJO_CONFIG_JETSPEED_VAR_NAME ).append( ".windowDecoration = \"" ).append( portletDecoration ).append( "\";" ).append( EOL );
523             }
524             decorationFactory.setDefaultDesktopPortletDecoration( portletDecoration );
525         }
526         
527         String desktopPageAjaxNavName = HeaderResource.HEADER_CONFIG_DESKTOP_PAGE_AJAXNAVIGATION;
528         String desktopPageAjaxNav = HeaderResourceLib.makeJSONBoolean( desktopConfigMap.get( desktopPageAjaxNavName ) );
529         if ( desktopPageAjaxNav != null && canAddHeaderNamedResourceFragment( desktopPageAjaxNavName, namedResourcesAddedFragmentsDefault, null ) )
530         {
531             desktopDojoConfigContent.append( "    " ).append( HeaderResource.HEADER_INTERNAL_DOJO_CONFIG_JETSPEED_VAR_NAME ).append( ".ajaxPageNavigation = " ).append( desktopPageAjaxNav ).append( ";" ).append( EOL );
532         }
533         
534         String desktopWindowTilingName = HeaderResource.HEADER_CONFIG_DESKTOP_WINDOW_TILING;
535         String desktopWindowTiling = HeaderResourceLib.makeJSONBoolean( desktopConfigMap.get( desktopWindowTilingName ) );
536         if ( desktopWindowTiling != null && canAddHeaderNamedResourceFragment( desktopWindowTilingName, namedResourcesAddedFragmentsDefault, null ) )
537         {
538             desktopDojoConfigContent.append( "    " ).append( HeaderResource.HEADER_INTERNAL_DOJO_CONFIG_JETSPEED_VAR_NAME ).append( ".windowTiling = " ).append( desktopWindowTiling ).append( ";" ).append( EOL );
539         }
540         
541         String desktopWindowHeightExpandName = HeaderResource.HEADER_CONFIG_DESKTOP_WINDOW_HEIGHT_EXPAND;
542         String desktopWindowHeightExpand = HeaderResourceLib.makeJSONBoolean( desktopConfigMap.get( desktopWindowHeightExpandName ) );
543         if ( desktopWindowHeightExpand != null && canAddHeaderNamedResourceFragment( desktopWindowHeightExpandName, namedResourcesAddedFragmentsDefault, null ) )
544         {
545             desktopDojoConfigContent.append( "    " ).append( HeaderResource.HEADER_INTERNAL_DOJO_CONFIG_JETSPEED_VAR_NAME ).append( ".windowHeightExpand = " ).append( desktopWindowHeightExpand ).append( ";" ).append( EOL );
546         }
547 
548         String desktopWindowHeightName = HeaderResource.HEADER_CONFIG_DESKTOP_WINDOW_HEIGHT;
549         String desktopWindowHeight = HeaderResourceLib.makeJSONInteger( desktopConfigMap.get( desktopWindowHeightName ), true );
550         if ( desktopWindowHeight != null && canAddHeaderNamedResourceFragment( desktopWindowHeightName, namedResourcesAddedFragmentsDefault, null ) )
551         {
552             desktopDojoConfigContent.append( "    " ).append( HeaderResource.HEADER_INTERNAL_DOJO_CONFIG_JETSPEED_VAR_NAME ).append( ".windowHeight = " ).append( desktopWindowHeight ).append( ";" ).append( EOL );
553         }
554         
555         String desktopWindowWidthName = HeaderResource.HEADER_CONFIG_DESKTOP_WINDOW_WIDTH;
556         String desktopWindowWidth = HeaderResourceLib.makeJSONInteger( desktopConfigMap.get( desktopWindowWidthName ), true );
557         if ( desktopWindowWidth != null && canAddHeaderNamedResourceFragment( desktopWindowWidthName, namedResourcesAddedFragmentsDefault, null ) )
558         {
559             desktopDojoConfigContent.append( "    " ).append( HeaderResource.HEADER_INTERNAL_DOJO_CONFIG_JETSPEED_VAR_NAME ).append( ".windowWidth = " ).append( desktopWindowWidth ).append( ";" ).append( EOL );
560         }
561         
562         List actionList = new ArrayList();
563         
564         String windowActionButtonOrderName = HeaderResource.HEADER_CONFIG_DESKTOP_WINDOW_ACTION_BUTTON_ORDER;
565         String actionButtonOrderContent = HeaderResourceLib.makeJSONStringArray( (List)desktopConfigMap.get( windowActionButtonOrderName ), actionList );
566         if ( actionButtonOrderContent != null && actionButtonOrderContent.length() > 0 )
567         {
568             if ( canAddHeaderNamedResourceFragment( windowActionButtonOrderName, namedResourcesAddedFragmentsDefault, null ) )
569             {
570                 desktopDojoConfigContent.append( "    " ).append( HeaderResource.HEADER_INTERNAL_DOJO_CONFIG_JETSPEED_VAR_NAME_SCOPE ).append( HeaderResource.DESKTOP_JSON_WINDOW_ACTION_BUTTON_ORDER ).append( " = " ).append( actionButtonOrderContent ).append( ";" ).append( EOL );
571             }
572         }
573         
574         String windowActionNoImageName = HeaderResource.HEADER_CONFIG_DESKTOP_WINDOW_ACTION_NOIMAGE;
575         String actionNoImageContent = HeaderResourceLib.makeJSONStringArray( (List)desktopConfigMap.get( windowActionNoImageName ), actionList );
576         if ( actionNoImageContent != null && actionNoImageContent.length() > 0 )
577         {
578             if ( canAddHeaderNamedResourceFragment( windowActionNoImageName, namedResourcesAddedFragmentsDefault, null ) )
579             {
580                 desktopDojoConfigContent.append( "    " ).append( HeaderResource.HEADER_INTERNAL_DOJO_CONFIG_JETSPEED_VAR_NAME_SCOPE ).append( HeaderResource.DESKTOP_JSON_WINDOW_ACTION_NOIMAGE ).append( " = " ).append( actionNoImageContent ).append( ";" ).append( EOL );
581             }
582         }
583         
584         String windowActionMenuOrderName = HeaderResource.HEADER_CONFIG_DESKTOP_WINDOW_ACTION_MENU_ORDER;
585         String actionMenuOrderContent = HeaderResourceLib.makeJSONStringArray( (List)desktopConfigMap.get( windowActionMenuOrderName ), actionList );
586         if ( actionMenuOrderContent != null && actionMenuOrderContent.length() > 0 )
587         {
588             if ( canAddHeaderNamedResourceFragment( windowActionMenuOrderName, namedResourcesAddedFragmentsDefault, null ) )
589             {
590                 desktopDojoConfigContent.append( "    " ).append( HeaderResource.HEADER_INTERNAL_DOJO_CONFIG_JETSPEED_VAR_NAME_SCOPE ).append( HeaderResource.DESKTOP_JSON_WINDOW_ACTION_MENU_ORDER ).append( " = " ).append( actionMenuOrderContent ).append( ";" ).append( EOL );
591             }
592         }
593 
594         headerDynamicConfigurationDefault.put( HeaderResource.HEADER_INTERNAL_CONFIG_DESKTOP_WINDOW_ACTION, actionList );
595         
596         String windowActionButtonTooltipName = HeaderResource.HEADER_CONFIG_DESKTOP_WINDOW_ACTION_BUTTON_TOOLTIP;
597         String windowActionButtonTooltip = HeaderResourceLib.makeJSONBoolean( desktopConfigMap.get( windowActionButtonTooltipName ) );
598         if ( windowActionButtonTooltip != null && canAddHeaderNamedResourceFragment( windowActionButtonTooltipName, namedResourcesAddedFragmentsDefault, null ) )
599         {
600             desktopDojoConfigContent.append( "    " ).append( HeaderResource.HEADER_INTERNAL_DOJO_CONFIG_JETSPEED_VAR_NAME_SCOPE ).append( HeaderResource.DESKTOP_JSON_WINDOW_ACTION_BUTTON_TOOLTIP ).append( " = " ).append( windowActionButtonTooltip ).append( ";" ).append( EOL );
601         }
602 
603         String windowActionButtonMaxName = HeaderResource.HEADER_CONFIG_DESKTOP_WINDOW_ACTION_BUTTON_MAX;
604         String windowActionButtonMax = HeaderResourceLib.makeJSONInteger( desktopConfigMap.get( windowActionButtonMaxName ), false );
605         if ( windowActionButtonMax != null && canAddHeaderNamedResourceFragment( windowActionButtonMaxName, namedResourcesAddedFragmentsDefault, null ) )
606         {
607             desktopDojoConfigContent.append( "    " ).append( HeaderResource.HEADER_INTERNAL_DOJO_CONFIG_JETSPEED_VAR_NAME_SCOPE ).append( HeaderResource.DESKTOP_JSON_WINDOW_ACTION_BUTTON_MAX ).append( " = " ).append( windowActionButtonMax ).append( ";" ).append( EOL );
608         }
609         
610         String windowIconEnabledName = HeaderResource.HEADER_CONFIG_DESKTOP_WINDOW_ICON_ENABLED;
611         String iconEnabledContent = HeaderResourceLib.makeJSONBoolean( desktopConfigMap.get( windowIconEnabledName ) );
612         if ( iconEnabledContent != null && iconEnabledContent.length() > 0 )
613         {
614             if ( canAddHeaderNamedResourceFragment( windowIconEnabledName, namedResourcesAddedFragmentsDefault, null ) )
615             {
616                 desktopDojoConfigContent.append( "    " ).append( HeaderResource.HEADER_INTERNAL_DOJO_CONFIG_JETSPEED_VAR_NAME_SCOPE ).append( HeaderResource.DESKTOP_JSON_WINDOW_ICON_ENABLED ).append( " = " ).append( iconEnabledContent ).append( ";" ).append( EOL );
617             }
618         }
619         
620         String windowIconPathName = HeaderResource.HEADER_CONFIG_DESKTOP_WINDOW_ICON_PATH;
621         String iconPathContent = (String)desktopConfigMap.get( windowIconPathName );
622         if ( iconPathContent != null && iconPathContent.length() > 0 )
623         {
624             if ( canAddHeaderNamedResourceFragment( windowIconPathName, namedResourcesAddedFragmentsDefault, null ) )
625             {
626                 desktopDojoConfigContent.append( "    " ).append( HeaderResource.HEADER_INTERNAL_DOJO_CONFIG_JETSPEED_VAR_NAME_SCOPE ).append( HeaderResource.DESKTOP_JSON_WINDOW_ICON_PATH ).append( " = \"" ).append( iconPathContent ).append( "\";" ).append( EOL );
627             }
628         }
629         
630         String windowTitlebarEnabledName = HeaderResource.HEADER_CONFIG_DESKTOP_WINDOW_TITLEBAR_ENABLED;
631         String titlebarEnabledContent = HeaderResourceLib.makeJSONBoolean( desktopConfigMap.get( windowTitlebarEnabledName ) );
632         if ( titlebarEnabledContent != null && titlebarEnabledContent.length() > 0 )
633         {
634             if ( canAddHeaderNamedResourceFragment( windowTitlebarEnabledName, namedResourcesAddedFragmentsDefault, null ) )
635             {
636                 desktopDojoConfigContent.append( "    " ).append( HeaderResource.HEADER_INTERNAL_DOJO_CONFIG_JETSPEED_VAR_NAME_SCOPE ).append( HeaderResource.DESKTOP_JSON_WINDOW_TITLEBAR_ENABLED ).append( " = " ).append( titlebarEnabledContent ).append( ";" ).append( EOL );
637             }
638         }
639         
640         String windowResizebarEnabledName = HeaderResource.HEADER_CONFIG_DESKTOP_WINDOW_RESIZEBAR_ENABLED;
641         String resizebarEnabledContent = HeaderResourceLib.makeJSONBoolean( desktopConfigMap.get( windowResizebarEnabledName ) );
642         if ( resizebarEnabledContent != null && resizebarEnabledContent.length() > 0 )
643         {
644             if ( canAddHeaderNamedResourceFragment( windowResizebarEnabledName, namedResourcesAddedFragmentsDefault, null ) )
645             {
646                 desktopDojoConfigContent.append( "    " ).append( HeaderResource.HEADER_INTERNAL_DOJO_CONFIG_JETSPEED_VAR_NAME_SCOPE ).append( HeaderResource.DESKTOP_JSON_WINDOW_TITLEBAR_ENABLED ).append( " = " ).append( resizebarEnabledContent ).append( ";" ).append( EOL );
647             }
648         }
649         
650         String pageActionButtonTooltipName = HeaderResource.HEADER_CONFIG_DESKTOP_PAGE_ACTION_BUTTON_TOOLTIP;
651         String pageActionButtonTooltip = HeaderResourceLib.makeJSONBoolean( desktopConfigMap.get( pageActionButtonTooltipName ) );
652         if ( pageActionButtonTooltip != null && canAddHeaderNamedResourceFragment( pageActionButtonTooltipName, namedResourcesAddedFragmentsDefault, null ) )
653         {
654             desktopDojoConfigContent.append( "    " ).append( HeaderResource.HEADER_INTERNAL_DOJO_CONFIG_JETSPEED_VAR_NAME ).append( ".pageActionButtonTooltip = " ).append( pageActionButtonTooltip ).append( ";" ).append( EOL );
655         }
656 
657         if ( desktopDojoConfigContent.length() > 0 )
658         {
659             namedResourcesDefault.put( HeaderResource.HEADER_SECTION_DOJO_CONFIG, desktopDojoConfigContent.toString() );
660         }
661         
662         StringBuffer desktopInitScript = new StringBuffer();
663         desktopInitScript.append( "    function doRender(bindArgs,portletEntityId) { " );
664         desktopInitScript.append( "jetspeed.doRender(bindArgs,portletEntityId); }" ).append( EOL );
665         desktopInitScript.append( "    function doAction(bindArgs,portletEntityId) { " );
666         desktopInitScript.append( "jetspeed.doAction(bindArgs,portletEntityId); }" ).append( EOL );
667         desktopInitScript.append( "    dojo.addOnLoad( jetspeed.initializeDesktop );" ).append( EOL );
668         if ( canAddHeaderNamedResourceFragment( "desktop.init", namedResourcesAddedFragmentsDefault, null ) )
669         {
670             namedResourcesDefault.put( HeaderResource.HEADER_SECTION_DESKTOP_INIT, desktopInitScript.toString() );
671             setNamedHeaderResourceProperties( HeaderResource.HEADER_SECTION_DESKTOP_INIT, HeaderResource.HEADER_TYPE_SCRIPT_BLOCK_START, null, headerDynamicConfigurationDefault );
672         }
673     }
674     
675     /***
676      * Read dojo header configuration settings and compile dojo header resource defaults
677      */
678     protected void initializeDojoHeaderConfigurationDefaults( Map dojoConfigMap, HashMap namedResourcesDefault, HashMap namedResourcesAddedFragmentsDefault, HashMap headerDynamicConfigurationDefault )
679     {
680         if ( dojoConfigMap == null )
681         {
682             dojoConfigMap = new HashMap();
683         }
684         String[] registryContent = new String[] { null };
685         
686         // add dojo.enable and dojo.path to dynamic configuration
687         String dojoEnableName = HeaderResource.HEADER_CONFIG_DOJO_ENABLE;
688         Object dojoEnableObj = dojoConfigMap.get( dojoEnableName );
689         String dojoEnable = ( ( dojoEnableObj == null ) ? (String)null : dojoEnableObj.toString() );
690         if ( dojoEnable == null || ! dojoEnable.equals( "true" ) )
691         {
692             dojoEnable = "false";
693         }
694         headerDynamicConfigurationDefault.put( dojoEnableName, dojoEnable );
695         String dojoPath = (String)dojoConfigMap.get( HeaderResource.HEADER_CONFIG_DOJO_PATH );
696         if ( dojoPath == null || dojoPath.length() == 0 )
697         {
698             dojoPath = "/javascript/dojo/";
699         }
700         headerDynamicConfigurationDefault.put( HeaderResource.HEADER_CONFIG_DOJO_PATH, dojoPath );
701         
702         // dojo parameters - djConfig parameters
703         boolean dojoDebugEnabled = false;
704         String dojoParamDebug = (String)dojoConfigMap.get( HeaderResource.HEADER_CONFIG_DOJO_PARAM_ISDEBUG );
705         String dojoParamDebugAtAllCosts = null;
706         if ( dojoParamDebug != null )
707         	dojoParamDebug = dojoParamDebug.toLowerCase();
708         if ( dojoParamDebug == null || dojoParamDebug.length() == 0 || dojoParamDebug.equals( "false" ) )
709         {
710         	dojoParamDebug = null;
711         }
712         else if ( dojoParamDebug.equals( "true" ) )
713         {
714         	dojoDebugEnabled = true;
715         	dojoParamDebugAtAllCosts = (String)dojoConfigMap.get( HeaderResource.HEADER_CONFIG_DOJO_PARAM_DEBUGALLCOSTS );
716         	if ( dojoParamDebugAtAllCosts != null )
717         	{
718         		dojoParamDebugAtAllCosts = dojoParamDebugAtAllCosts.toLowerCase();
719         		if ( ! dojoParamDebugAtAllCosts.equals( "true") )
720         		{
721         			dojoParamDebugAtAllCosts = null;
722         		}
723         	}
724         }
725         
726         String dojoParamPreventBackBtnFix = (String)dojoConfigMap.get( HeaderResource.HEADER_CONFIG_DOJO_PARAM_PREVENT_BACKBUTTON_FIX );
727         String dojoParams = (String)dojoConfigMap.get( HeaderResource.HEADER_CONFIG_DOJO_PARAMS );
728         if ( dojoParamDebug != null || dojoParamDebugAtAllCosts != null || dojoParamPreventBackBtnFix != null || dojoParams != null )
729         {
730             StringBuffer dojoConfigContent = new StringBuffer();
731             boolean addedMembers = false;
732             if ( dojoParams != null && dojoParams.length() > 0 )
733             {
734                 dojoConfigContent.append( dojoParams );
735                 addedMembers = true;
736             }
737             if ( dojoParamDebug != null && dojoParamDebug.length() > 0 )
738             {
739                 if ( addedMembers )
740                 {
741                     dojoConfigContent.append( ", " );
742                 }
743                 dojoConfigContent.append( "isDebug: " ).append( dojoParamDebug ) ;
744                 addedMembers = true;
745             }
746             if ( dojoParamDebugAtAllCosts != null && dojoParamDebugAtAllCosts.length() > 0 )
747             {
748                 if ( addedMembers )
749                 {
750                     dojoConfigContent.append( ", " );
751                 }
752                 dojoConfigContent.append( "debugAtAllCosts: " ).append( dojoParamDebugAtAllCosts ) ;
753                 addedMembers = true;
754             }
755             if ( dojoParamPreventBackBtnFix != null && dojoParamPreventBackBtnFix.length() > 0 )
756             {
757                 if ( addedMembers )
758                 {
759                     dojoConfigContent.append( ", " );
760                 }
761                 dojoConfigContent.append( "preventBackButtonFix: " ).append( dojoParamPreventBackBtnFix ) ;
762                 addedMembers = true;
763             }
764             if ( addedMembers )
765             {
766                 dojoConfigContent.append( ", " );
767             }
768             dojoConfigContent.append( HeaderResource.HEADER_INTERNAL_JETSPEED_VAR_NAME ).append( ": {}" ) ;
769             addedMembers = true;
770             
771             if ( canAddHeaderNamedResourceFragment( HeaderResource.HEADER_CONFIG_DOJO_PARAMS, namedResourcesAddedFragmentsDefault, registryContent ) )
772             {
773                 String dojoParamContent = dojoConfigContent.toString();
774                 if ( registryContent[0] != null )
775                 {
776                     dojoParamContent = registryContent[0];
777                 }
778                 if ( dojoParamContent.length() > 0 )
779                 {
780                     namedResourcesDefault.put( HeaderResource.HEADER_SECTION_DOJO_PARAMETERS, ( "    var djConfig = {" + dojoParamContent + "};" + EOL ) );
781                 }
782             }
783             registerAndOrderNamedHeaderResource( HeaderResource.HEADER_SECTION_DOJO_PARAMETERS, HeaderResource.HEADER_TYPE_SCRIPT_BLOCK_START, dojoEnableName, headerDynamicConfigurationDefault );
784         }
785         
786         // dojo preinit - for automatically added members to djConfig (eg. djConfig.baseScriptUri="...")
787         //    - adding to order only at this point
788         //    - if header contains content, generated content will not be added
789         registerAndOrderNamedHeaderResource( HeaderResource.HEADER_SECTION_DOJO_PREINIT, null, dojoEnableName, headerDynamicConfigurationDefault );
790         
791         // dojo config - for adding members to djConfig (eg. djConfig.parseWidgets=false)
792         //    - adding to order only at this point
793         registerAndOrderNamedHeaderResource( HeaderResource.HEADER_SECTION_DOJO_CONFIG, null, dojoEnableName, headerDynamicConfigurationDefault );
794         
795         // dojo init - script tag for dojo.js
796         //    - adding to order only at this point
797         //    - if header contains content, generated content will not be added
798         registerAndOrderNamedHeaderResource( HeaderResource.HEADER_SECTION_DOJO_INIT, HeaderResource.HEADER_TYPE_SCRIPT_TAG, dojoEnableName, headerDynamicConfigurationDefault );
799         
800         // dojo requires - core libraries
801         List dojoRequiresCore = (List)dojoConfigMap.get( HeaderResource.HEADER_CONFIG_DOJO_REQUIRES_CORE );
802         if ( dojoRequiresCore != null && dojoRequiresCore.size() > 0 )
803         {
804             StringBuffer dojoRequiresContent = new StringBuffer();
805             Iterator dojoRequiresCoreIter = dojoRequiresCore.iterator();
806             while ( dojoRequiresCoreIter.hasNext() )
807             {
808                 String dojoReq = (String)dojoRequiresCoreIter.next();
809                 if ( dojoReq != null && dojoReq.length() > 0 )
810                 {
811                     if ( canAddHeaderNamedResourceFragment( dojoReq, namedResourcesAddedFragmentsDefault, registryContent ) )
812                     {
813                         if ( registryContent[0] != null )
814                         {
815                             String dojoReqFromRegistry = HeaderResourceLib.makeJavascriptStatement( registryContent[0], "    ", true );
816                             if ( dojoReqFromRegistry.length() > 0 )
817                             {
818                                 dojoRequiresContent.append( registryContent[0] );
819                             }
820                         }
821                         else
822                         {
823                             dojoRequiresContent.append( "    dojo.require(\"").append( dojoReq ).append( "\");" ).append( EOL );
824                         }
825                     }
826                 }
827             }
828             namedResourcesDefault.put( HeaderResource.HEADER_SECTION_DOJO_REQUIRES_CORE, dojoRequiresContent.toString() );
829             registerAndOrderNamedHeaderResource( HeaderResource.HEADER_SECTION_DOJO_REQUIRES_CORE, null, dojoEnableName, headerDynamicConfigurationDefault );
830         }
831         
832         // dojo modules path definition
833         List dojoModulesPath = (List)dojoConfigMap.get( HeaderResource.HEADER_CONFIG_DOJO_MODULES_PATH );
834         if ( dojoModulesPath != null && dojoModulesPath.size() > 0 )
835         {
836             StringBuffer dojoModulesPathContent = new StringBuffer();
837             boolean addedContent = false;
838             Iterator dojoModulesPathIter = dojoModulesPath.iterator();
839             while ( dojoModulesPathIter.hasNext() )
840             {
841                 String dojoModule = (String)dojoModulesPathIter.next();
842                 if ( dojoModule != null && dojoModule.length() > 0 )
843                 {
844                     if ( canAddHeaderNamedResourceFragment( dojoModule, namedResourcesAddedFragmentsDefault, registryContent ) )
845                     {
846                         String dojoModuleContent = null;
847                         if ( registryContent[0] != null )
848                         {
849                             dojoModuleContent = registryContent[0];
850                         }
851                         else
852                         {
853                             dojoModuleContent = dojoModule;
854                         }
855                         dojoModuleContent = HeaderResourceLib.makeJavascriptStatement( dojoModuleContent, "    ", true );
856                         if ( dojoModuleContent.length() > 0 )
857                         {
858                             dojoModulesPathContent.append( dojoModuleContent );
859                             addedContent = true;
860                         }
861                     }
862                 }
863             }
864             if ( addedContent )
865             {
866                 namedResourcesDefault.put( HeaderResource.HEADER_SECTION_DOJO_MODULES_PATH, dojoModulesPathContent.toString() );
867                 registerAndOrderNamedHeaderResource( HeaderResource.HEADER_SECTION_DOJO_MODULES_PATH, null, dojoEnableName, headerDynamicConfigurationDefault );
868             }
869         }
870         
871         // dojo modules namespace definition
872         List dojoModulesNamespace = (List)dojoConfigMap.get( HeaderResource.HEADER_CONFIG_DOJO_MODULES_NAMESPACE );
873         if ( dojoModulesNamespace != null && dojoModulesNamespace.size() > 0 )
874         {
875             StringBuffer dojoModulesNamespaceContent = new StringBuffer();
876             boolean addedContent = false;
877             Iterator dojoModulesNamespaceIter = dojoModulesNamespace.iterator();
878             while ( dojoModulesNamespaceIter.hasNext() )
879             {
880                 String dojoModuleWidget = (String)dojoModulesNamespaceIter.next();
881                 if ( dojoModuleWidget != null && dojoModuleWidget.length() > 0 )
882                 {
883                     if ( canAddHeaderNamedResourceFragment( dojoModuleWidget, namedResourcesAddedFragmentsDefault, registryContent ) )
884                     {
885                         String dojoModuleContent = null;
886                         if ( registryContent[0] != null )
887                         {
888                             dojoModuleContent = registryContent[0];
889                         }
890                         else
891                         {
892                             dojoModuleContent = dojoModuleWidget;
893                         }
894                         dojoModuleContent = HeaderResourceLib.makeJavascriptStatement( dojoModuleContent, "    ", true );
895                         if ( dojoModuleContent.length() > 0 )
896                         {
897                             dojoModulesNamespaceContent.append( dojoModuleContent );
898                             addedContent = true;
899                         }
900                     }
901                 }
902             }
903             if ( addedContent )
904             {
905                 namedResourcesDefault.put( HeaderResource.HEADER_SECTION_DOJO_MODULES_NAMESPACE, dojoModulesNamespaceContent.toString() );
906                 // registerAndOrderNamedHeaderResource called below
907             }
908         }
909         
910         // dojo requires - module libraries (from add-on modules)
911         List dojoRequiresModules = (List)dojoConfigMap.get( HeaderResource.HEADER_CONFIG_DOJO_REQUIRES_MODULES );
912         if ( dojoRequiresModules != null && dojoRequiresModules.size() > 0 )
913         {
914         	HashMap addedReqs = null;
915         	if ( dojoDebugEnabled )
916         		addedReqs = new HashMap();
917             StringBuffer dojoRequiresContent = new StringBuffer();
918             Iterator dojoRequiresModulesIter = dojoRequiresModules.iterator();
919             while ( dojoRequiresModulesIter.hasNext() )
920             {
921                 String dojoReq = (String)dojoRequiresModulesIter.next();
922                 if ( dojoReq != null && dojoReq.length() > 0 )
923                 {
924                     if ( canAddHeaderNamedResourceFragment( dojoReq, namedResourcesAddedFragmentsDefault, registryContent ) )
925                     {
926                         if ( registryContent[0] != null )
927                         {
928                             String dojoReqFromRegistry = HeaderResourceLib.makeJavascriptStatement( registryContent[0], "    ", true );
929                             if ( dojoReqFromRegistry.length() > 0 )
930                             {
931                                 dojoRequiresContent.append( registryContent[0] );
932                             }
933                         }
934                         else
935                         {
936                             dojoRequiresContent.append( "    dojo.require(\"").append( dojoReq ).append( "\");" ).append( EOL );
937                             if ( dojoDebugEnabled )
938                             	addedReqs.put( dojoReq, dojoReq ); 
939                         }
940                     }
941                 }
942             }
943             if ( dojoDebugEnabled )
944             {
945             	if ( addedReqs.get( HeaderResource.HEADER_DEBUG_REQUIRES ) == null )
946             	{
947             		dojoRequiresContent.append( "    dojo.require(\"").append( HeaderResource.HEADER_DEBUG_REQUIRES ).append( "\");" ).append( EOL );
948             	}
949             }            
950             namedResourcesDefault.put( HeaderResource.HEADER_SECTION_DOJO_REQUIRES_MODULES, dojoRequiresContent.toString() );
951             registerAndOrderNamedHeaderResource( HeaderResource.HEADER_SECTION_DOJO_REQUIRES_MODULES, null, dojoEnableName, headerDynamicConfigurationDefault );
952         }
953         
954         // dojo writeincludes
955         //    - adding to order only at this point
956         //    - if header contains content, generated content will not be added
957         registerAndOrderNamedHeaderResource( HeaderResource.HEADER_SECTION_DOJO_WRITEINCLUDES, HeaderResource.HEADER_TYPE_SCRIPT_BLOCK_START, dojoEnableName, headerDynamicConfigurationDefault );
958         
959         // dojo widget module - register widget packages (eg. dojo.widget.manager.registerWidgetPackage('jetspeed.ui.widget'))
960         //    - default resource added above
961         registerAndOrderNamedHeaderResource( HeaderResource.HEADER_SECTION_DOJO_MODULES_NAMESPACE, HeaderResource.HEADER_TYPE_SCRIPT_BLOCK_START, dojoEnableName, headerDynamicConfigurationDefault );
962         
963         // dojo style bodyexpand
964         setNamedHeaderResourceProperties( HeaderResource.HEADER_SECTION_DOJO_STYLE_BODYEXPAND, HeaderResource.HEADER_TYPE_STYLE_BLOCK, dojoEnableName, headerDynamicConfigurationDefault );
965         
966         // dojo style bodyexpand noscroll
967         setNamedHeaderResourceProperties( HeaderResource.HEADER_SECTION_DOJO_STYLE_BODYEXPAND_NOSCROLL, HeaderResource.HEADER_TYPE_STYLE_BLOCK, dojoEnableName, headerDynamicConfigurationDefault );
968     }
969 
970     
971     /***
972      * Builds the portlet set defined in the context into a portlet tree.
973      * 
974      * @return Unique Portlet Entity ID
975      */
976     public void build( RequestContext context ) throws JetspeedException, IOException
977     {
978         ContentPage page = context.getPage();
979         if ( null == page )
980         {
981             throw new JetspeedException( "Failed to find PSML Pin ContentPageAggregator.build" );
982         }
983 
984         ContentFragment root = page.getRootContentFragment();
985 
986         if ( root == null )
987         {
988             throw new JetspeedException( "No root ContentFragment found in ContentPage" );
989         }
990 
991         // add named-resources and named-resources-added maps as request attributes
992         Map dynamicConfigDefault = getHeaderDynamicConfigurationDefault();
993         Map namedResourcesDefault = getHeaderNamedResourcesDefault();
994         Map namedResourcesAddedFragmentsDefault = getHeaderNamedResourcesAddedFragmentsDefault();
995         
996         /*if ( log.isDebugEnabled() && namedResourcesDefault != null )
997         {
998             Iterator namedResourcesDefaultIter = namedResourcesDefault.entrySet().iterator();
999             while ( namedResourcesDefaultIter.hasNext() )
1000             {
1001                 Map.Entry rsrcEntry = (Map.Entry)namedResourcesDefaultIter.next();
1002                 Object rsrcVal = rsrcEntry.getValue();
1003                 log.debug( rsrcEntry.getKey().toString() + ": " + EOL + ( rsrcVal != null ? rsrcVal.toString() : "null" ) );
1004             }
1005         }*/
1006         
1007         if ( dynamicConfigDefault != null || namedResourcesDefault != null || namedResourcesAddedFragmentsDefault != null )
1008         {
1009             Map existingNamedResources = (Map)context.getAttribute( PortalReservedParameters.HEADER_NAMED_RESOURCE_ATTRIBUTE );
1010             if ( existingNamedResources == null )
1011             {
1012                 if ( dynamicConfigDefault == null )
1013                 {
1014                     context.setAttribute( PortalReservedParameters.HEADER_CONFIGURATION_ATTRIBUTE, new HashMap() );
1015                 }
1016                 else
1017                 {
1018                     HashMap dynamicConfig = new HashMap();
1019                     Iterator hConfigEntryIter = dynamicConfigDefault.entrySet().iterator();
1020                     while ( hConfigEntryIter.hasNext() )
1021                     {
1022                         Map.Entry hConfigEntry = (Map.Entry)hConfigEntryIter.next();
1023                         Object hConfigKey = hConfigEntry.getKey();
1024                         Object hConfigVal = hConfigEntry.getValue();
1025                         if ( hConfigVal instanceof Map )
1026                         {
1027                             dynamicConfig.put( hConfigKey, new HashMap( (Map)hConfigVal ) );
1028                         }
1029                         else if ( hConfigVal instanceof List )
1030                         {
1031                             dynamicConfig.put( hConfigKey, new ArrayList( (List)hConfigVal ) );
1032                         }
1033                         else
1034                         {
1035                             dynamicConfig.put( hConfigKey, hConfigVal );
1036                         }
1037                     }
1038                     context.setAttribute( PortalReservedParameters.HEADER_CONFIGURATION_ATTRIBUTE, dynamicConfig );
1039                 }
1040                 
1041                 if ( namedResourcesDefault != null )
1042                 {
1043                     context.setAttribute( PortalReservedParameters.HEADER_NAMED_RESOURCE_ATTRIBUTE, new HashMap( namedResourcesDefault ) );
1044                 }
1045                 if ( namedResourcesAddedFragmentsDefault != null )
1046                 {
1047                     context.setAttribute( PortalReservedParameters.HEADER_NAMED_RESOURCE_ADDED_FRAGMENTS_ATTRIBUTE, new HashMap( namedResourcesAddedFragmentsDefault ) );
1048                 }
1049             }
1050         }
1051         if ( getHeaderResourceRegistry() != null )
1052         {
1053             context.setAttribute( PortalReservedParameters.HEADER_NAMED_RESOURCE_REGISTRY_ATTRIBUTE, getHeaderResourceRegistry() );
1054         }
1055         
1056         // handle maximized state
1057         boolean atLeastOneHasHeaderPhase = false;
1058         NavigationalState nav = context.getPortalURL().getNavigationalState();
1059         PortletWindow window = nav.getMaximizedWindow();
1060         if ( null != window )
1061         {
1062             ContentFragment maxedContentFragment = page.getContentFragmentById( window.getId().toString() );
1063             if ( maxedContentFragment != null )
1064             {
1065                 atLeastOneHasHeaderPhase = renderHeaderFragment( context, maxedContentFragment );
1066             }
1067         }
1068         else
1069         {
1070             atLeastOneHasHeaderPhase = aggregateAndRender( root, context, page );
1071         }
1072         
1073         if ( atLeastOneHasHeaderPhase )
1074         {
1075             
1076         }
1077     }
1078 
1079     protected boolean aggregateAndRender( ContentFragment fragment, RequestContext context, ContentPage page )
1080             throws FailedToRenderFragmentException
1081     {
1082         boolean atLeastOneHasHeaderPhase = false;
1083         boolean hasHeaderPhase = false;
1084         if ( fragment.getContentFragments() != null && fragment.getContentFragments().size() > 0 )
1085         {
1086             Iterator children = fragment.getContentFragments().iterator();
1087             while (children.hasNext())
1088             {
1089                 ContentFragment child = (ContentFragment) children.next();
1090                 if ( ! "hidden".equals( fragment.getState() ) )
1091                 {
1092                     hasHeaderPhase = aggregateAndRender( child, context, page );
1093                     if ( hasHeaderPhase )
1094                     {
1095                         atLeastOneHasHeaderPhase = true;
1096                     }
1097                 }
1098             }
1099         }
1100         hasHeaderPhase = renderHeaderFragment( context, fragment );
1101         if ( hasHeaderPhase )
1102         {
1103             atLeastOneHasHeaderPhase = true;
1104         }
1105         return atLeastOneHasHeaderPhase;
1106     }
1107     
1108     protected boolean renderHeaderFragment( RequestContext context, ContentFragment fragment )
1109     {
1110         try
1111         {
1112             if ( !fragment.getType().equals( ContentFragment.LAYOUT ) )
1113             {
1114                 PortletWindow portletWindow = getPortletWindowAccessor().getPortletWindow( fragment );
1115                 PortletDefinition pd = portletWindow.getPortletEntity().getPortletDefinition();
1116                 if ( pd != null && getPortletFactory().isPortletApplicationRegistered((PortletApplication)pd.getPortletApplicationDefinition() ) )
1117                 {
1118                     String portletApplicationContextPath = pd.getPortletApplicationDefinition().getWebApplicationDefinition().getContextRoot();
1119                     Portlet portlet = getPortletFactory().getPortletInstance( context.getConfig().getServletContext().getContext( portletApplicationContextPath ), pd ).getRealPortlet();            
1120                     if ( portlet != null && portlet instanceof SupportsHeaderPhase )
1121                     {
1122                         log.debug( "renderHeaderFragment: " + pd.getName() + " supports header phase" );
1123                         
1124                         HeaderResource hr = getHeaderResourceFactory().getHeaderResource( context, this.baseUrlAccess, isDesktop(), getHeaderConfiguration() );
1125                         PortletHeaderRequest headerRequest = new PortletHeaderRequestImpl( context, portletWindow, portletApplicationContextPath );
1126                         PortletHeaderResponse headerResponse = new PortletHeaderResponseImpl( context, hr, isDesktop(), getHeaderConfiguration(), getHeaderResourceRegistry() );
1127                         ((SupportsHeaderPhase)portlet).doHeader( headerRequest, headerResponse );
1128                         return true;
1129                     }
1130                 }
1131             }
1132             return false;
1133         }
1134         catch ( Exception e )
1135         {
1136             log.error( "renderHeaderFragment failed", e );
1137         }
1138         return false;
1139     }
1140     
1141     protected PortletFactory getPortletFactory()
1142     {
1143         return this.factory;
1144     }
1145     protected PortletWindowAccessor getPortletWindowAccessor()
1146     {
1147         return this.windowAccessor;
1148     }
1149     protected HeaderResourceFactory getHeaderResourceFactory()
1150     {
1151         return this.headerResourceFactory;
1152     }
1153     protected boolean isDesktop()
1154     {
1155         return this.isDesktop;
1156     }
1157     protected Map getHeaderConfiguration()
1158     {
1159         return this.headerConfiguration;
1160     }
1161     protected Map getHeaderResourceRegistry()
1162     {
1163         return this.headerResourceRegistry;
1164     }
1165     protected Map getHeaderDynamicConfigurationDefault()
1166     {
1167         return this.headerDynamicConfigurationDefault;
1168     }
1169     protected Map getHeaderNamedResourcesDefault()
1170     {
1171         return this.headerNamedResourcesDefault;
1172     }
1173     protected Map getHeaderNamedResourcesAddedFragmentsDefault()
1174     {
1175         return this.headerNamedResourcesAddedFragmentsDefault;
1176     }
1177     protected BasePortalURL getBaseUrlAccess()
1178     {
1179         return this.baseUrlAccess;
1180     }
1181 }