View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.myfaces.custom.dojo;
21  
22  import org.apache.commons.lang.StringUtils;
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  import org.apache.myfaces.renderkit.html.util.AddResource;
26  import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
27  import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
28  
29  import javax.faces.component.UIComponent;
30  import javax.faces.context.FacesContext;
31  import javax.faces.context.ResponseWriter;
32  import javax.servlet.http.HttpServletRequest;
33  import java.io.IOException;
34  import java.lang.reflect.InvocationTargetException;
35  import java.lang.reflect.Method;
36  import java.util.*;
37  import java.util.Map.Entry;
38  
39  /**
40   * Utils class for the dojo infrastructure to ease the component building
41   * mechanisms note this class uses its own double entries filter due to the fact
42   * that we can mix and match header and body scripts as needed (we do not want
43   * to lose portal functionality do we?)
44   *
45   * @author Werner Punz (latest modification by $Author: lu4242 $)
46   * @version $Revision: 697985 $ $Date: 2006-09-08 20:56:28 +0000 (Fri, 08 Sep
47   *          2006) $
48   */
49  public final class DojoUtils {
50      private static final String MYFACES_DOJO_DEBUGCONSOLE_ID     = "myfaces_Dojo_Debugger";
51  
52      private static final String DEBUG_CONSOLE_TYPE               = "DebugConsole";
53  
54      private static final String LAYOUT_ALIGN_ATTR                = "layoutAlign";
55  
56      private static final String DISPLAY_CLOSE_ACTION_ATTR        = "displayCloseAction";
57  
58      private static final String RESIZABLE_ATTR                   = "resizable";
59  
60      private static final String HAS_SHADOW_ATTR                  = "hasShadow";
61  
62      private static final String CONSTRAIN_TO_CONTAINER_ATTR      = "constrainToContainer";
63  
64      private static final String ICON_SRC_ATTR                    = "iconSrc";
65  
66      private static final String TITLE_ATTR                       = "title";
67  
68      private static final String INCL_TYPE_REQ_KEY                = "DOJO_DEVELOPMENT_INCLUDE";
69  
70      private static final Log    log                              = LogFactory.getLog(DojoUtils.class);
71  
72      private static final String DOJO_PROVIDE                     = "dojo.provide:";
73  
74      private static final String DOJO_REQUIRE                     = "dojo.require:";
75  
76      private static final String DOJO_NAMESPACE                   = "dojo.namespace:";
77  
78      private static final String DJCONFIG_INITKEY                 = "/*djconfig init*/";
79  
80      private static final String BODY_SCRIPT_INFOS_ATTRIBUTE_NAME = "bodyScriptInfos";
81  
82      private static final String DOJO_FILE_UNCOMPRESSED           = "dojo.js.uncompressed.js";
83  
84      private static final String DOJO_FILE                        = "dojo.js";
85  
86      private static final String DJCONFIG_REQ_KEY                 = "MYFACES_DJCONFIG";
87  
88      private static final String DOJOEXTENSIONS_NAMESPACE         = "dojo.setModulePrefix('extensions', '../dojoextensions.ResourceLoader');";
89  
90      private DojoUtils() {
91          // nope
92      }
93  
94      /**
95       * creates a dojoed attribute map upon the given array of attribute names
96       *
97       * @param facesContext
98       *            standard faces context used internally
99       * @param attributeNames
100      *            string array of traversable attribute names
101      * @param component
102      *            the source component with the values set
103      * @return a map which resembles the attribute map for further processing
104      */
105     public static Map getAttributeMap(FacesContext facesContext, String[] attributeNames, UIComponent component) {
106         Log log = null;
107 
108         Class componentClass = component.getClass();
109         Map returnMap = new HashMap();
110         for (int cnt = 0; cnt < attributeNames.length; cnt++) {
111             try {
112                 String attributeName = attributeNames[cnt];
113                 //the dojo attributes deal with different ids than the rest
114                 if (attributeName.equals("id") || attributeName.equals("widgetId")) {
115                     String calculatedId = DojoUtils.calculateWidgetId(facesContext, component);
116                     returnMap.put("id", calculatedId);
117                 } else {
118                     String attributeCasedName = attributeName.substring(0, 1).toUpperCase() + attributeName.substring(1);
119                     String getForm = "get" + attributeCasedName; // to prevent multiple creating in finding
120                     String isForm = "is" + attributeCasedName; // to prevent multiple creating in finding
121                     Method m = null;
122                     // finding getter in hiearchy: try current class for "get" and "is" form, if NOT found, try superclass
123                     // doesn't use getMethod() to avoid walking whole hiearchy for wrong form in case of "is"
124                     // and getMethod() uses getSuperClass() anyway, so no performance hit this way + ability to invoke protected methods
125                     while ((componentClass != null) && (m == null)) {
126                         m = componentClass.getDeclaredMethod(getForm, null);
127                         if (m == null) {
128                             // try alternative method name for dealing with Booleans
129                          m = componentClass.getDeclaredMethod(isForm, null);
130                         }
131                         if (m == null) {
132                             // load superclass
133                             componentClass = componentClass.getSuperclass(); // null in case of componentClass == Object
134                         }
135                     }
136                     if (m != null) {
137                         Object execRetval = m.invoke(component, null);
138                         if (execRetval != null)
139                             returnMap.put(attributeName, execRetval);
140                     }
141                 }
142             } catch (Exception e) {
143                 if (log == null)
144                     log = LogFactory.getLog(DojoUtils.class);
145                 // this should not happen but can
146                 log.error("getAttributeMap", e);
147             }
148         }
149         return returnMap;
150     }
151 
152     /**
153      * adds a debug console to the output this is for helping to debug the dojo
154      * system a debug:true is required for this to work properly it will not be
155      * set by this method (due to the avoidance of unwanted automatisms causing
156      * sideefects)
157      *
158      * @param facesContext
159      * @param component
160      * @return
161      */
162     public static void addDebugConsole(FacesContext facesContext, UIComponent component) throws IOException {
163 
164         /* check whether we have a debugging flag already set */
165         if (isInlineScriptSet(facesContext, "/*DOJO DEBUGCONSOLE ON*/"))
166             return;
167 
168         AddResource addResource = AddResourceFactory.getInstance(facesContext);
169         addResource.addInlineScriptAtPosition(facesContext, AddResource.HEADER_BEGIN, "/*DOJO DEBUGCONSOLE ON*/");
170 
171         ResponseWriter writer = facesContext.getResponseWriter();
172         // we for now have to break html until the dynamic creation
173         // isses are resolved, so hold on for this messy code now
174         // Since this is for debugging purposes only, we can live with it
175 
176         writer.startElement(HTML.DIV_ELEM, component);
177         writer.writeAttribute(HTML.ID_ATTR, MYFACES_DOJO_DEBUGCONSOLE_ID, null);
178         writer.writeAttribute(HTML.STYLE_ATTR, "width: 400px; height: 500px; left: 200px;", null);
179         writer.endElement(HTML.DIV_ELEM);
180 
181         Map attributeMap = new HashMap();
182         attributeMap.put(TITLE_ATTR, "MyFaces Dojo Debug console");
183         attributeMap.put(ICON_SRC_ATTR, "images/flatScreen.gif");
184         attributeMap.put(CONSTRAIN_TO_CONTAINER_ATTR, new Integer(1));
185         attributeMap.put(HAS_SHADOW_ATTR, new Boolean(true));
186         attributeMap.put(RESIZABLE_ATTR, new Boolean(true));
187         attributeMap.put(DISPLAY_CLOSE_ACTION_ATTR, new Boolean(true));
188         attributeMap.put(LAYOUT_ALIGN_ATTR, "client");
189         renderWidgetInitializationCode(writer, component, DEBUG_CONSOLE_TYPE, attributeMap, MYFACES_DOJO_DEBUGCONSOLE_ID, true);
190     }
191 
192     /**
193      * check if dojo is going to be used 
194      */
195     public static boolean isDojoInitialized(FacesContext facesContext)
196     {
197         return isInlineScriptCheck(facesContext, DJCONFIG_INITKEY);
198     }
199 
200     public static void addMainInclude(FacesContext facesContext, UIComponent component, String javascriptLocation, DojoConfig config) throws IOException {
201 
202         AddResource addResource = AddResourceFactory.getInstance(facesContext);
203 
204         /*
205          * var djConfig = { isDebug: false }; TODO add a saner handling of
206          * collecting all djconfig data and then merging it
207          */
208         if (!isInlineScriptSet(facesContext, DJCONFIG_INITKEY)) {
209             addResource.addInlineScriptAtPosition(facesContext, AddResource.HEADER_BEGIN, DJCONFIG_INITKEY);
210             addResource.addInlineScriptAtPosition(facesContext, AddResource.HEADER_BEGIN, config.toString());
211 
212             String dojofile = ((getExpanded(facesContext) != null) && getExpanded(facesContext).booleanValue()) ? DOJO_FILE_UNCOMPRESSED : DOJO_FILE;
213 
214             if (javascriptLocation != null) {
215                 addResource.addJavaScriptAtPosition(facesContext, AddResource.HEADER_BEGIN, javascriptLocation + dojofile);
216             } else {
217                 /*
218                  * ResponseWriter writer = facesContext.getResponseWriter();
219                  * writer.startElement(HTML.SCRIPT_ELEM,component);
220                  *
221                  * MyFacesResourceHandler handler = new
222                  * MyFacesResourceHandler(DojoResourceLoader.class, dojofile);
223                  * String uri = handler.getResourceUri(facesContext); uri =
224                  * uri.replaceAll("dojo\\.js\\;jsessionid(.)*\\\"","dojo.js");
225                  * writer.writeAttribute(HTML.SRC_ATTR, uri, null);
226                  *
227                  * writer.endElement(HTML.SCRIPT_ELEM);
228                  * addResource.addJavaScriptAtPosition(facesContext,
229                  * AddResource.HEADER_BEGIN, DojoResourceLoader.class,
230                  * dojofile);
231                  */
232 
233                 addResource.addJavaScriptAtPositionPlain(facesContext, AddResource.HEADER_BEGIN, DojoResourceLoader.class, dojofile);
234             }
235             addResource.addInlineScriptAtPosition(facesContext, AddResource.HEADER_BEGIN, DOJOEXTENSIONS_NAMESPACE);
236         }
237     }
238 
239     /**
240      * adds a new namespace location to the mix
241      *
242      * @param facesContext
243      *            the faces context which is used internally
244      * @param component
245      *            the affected component
246      * @param namespace
247      *            the namespace which has to be applied
248      * @param location
249      *            the script location
250      * @throws IOException
251      * @link http://blog.dojotoolkit.org/2006/01/11/putting-your-code-outside-of-the-dojo-source-tree
252      */
253     public static void addNamespace(FacesContext facesContext, UIComponent component, String namespace, String location) throws IOException {
254 
255         if (isInlineScriptSet(facesContext, DOJO_NAMESPACE + namespace))
256             return;
257 
258         String namespaceStr = createNamespaceScript(namespace, location);
259         writeInlineScript(facesContext, component, namespaceStr);
260     }
261 
262     /**
263      * adds a dojo provide to the current list of definitions within the header
264      *
265      * @param context
266      *            the faces context for accessing the resources internally
267      * @param provided
268      *            the package with the class provided by this implementation
269      * @see <a
270      *      href="http://dojotoolkit.org/docs/fast_widget_authoring.html">Dojo-Widget-Authoring</a>
271      *      for an example on this
272      */
273     public static void addProvide(FacesContext context, String provided) {
274 
275         if (isInlineScriptSet(context, DOJO_PROVIDE + provided))
276             return;
277 
278         AddResource addResource = AddResourceFactory.getInstance(context);
279         String providedBuilder = createDojoProvideScript(provided);
280 
281         addResource.addInlineScriptAtPosition(context, AddResource.HEADER_BEGIN, providedBuilder);
282     }
283 
284     /**
285      * adds a dojo provide
286      *
287      * @param facesContext
288      * @param component
289      * @param provided
290      * @throws IOException
291      */
292     public static void addProvide(FacesContext facesContext, UIComponent component, String provided) throws IOException {
293 
294         if (isInlineScriptSet(facesContext, DOJO_PROVIDE + provided))
295             return;
296 
297         String providedBuilder = createDojoProvideScript(provided);
298 
299         writeInlineScript(facesContext, component, providedBuilder);
300 
301     }
302 
303     /**
304      * convenience method for easier requires handling
305      * @param facesContext standard faces context
306      * @param component the component
307      * @param requires an array of requires which is rendered into single dojo.require statements
308      * @throws IOException
309      */
310     public static void addRequire(FacesContext facesContext, UIComponent component, String[] requires) throws IOException {
311         for (int cnt = 0; cnt < requires.length; cnt++)
312             addRequire(facesContext, component, requires[cnt]);
313     }
314 
315     /**
316      * adds a dojo require include to our mix of stuff used
317      *
318      * @param facesContext
319      * @param required
320      */
321     public static void addRequire(FacesContext facesContext, UIComponent component, String required) throws IOException {
322 
323         if (isInlineScriptSet(facesContext, DOJO_REQUIRE + required))
324             return;
325 
326         String requireAsScript = createDojoRequireString(required);
327         writeInlineScript(facesContext, component, requireAsScript);
328     }
329 
330     /**
331      * creates a debug statement for the debug console
332      *
333      * @param stmnt
334      *            the debug message displayed by the debug console
335      * @return javaScriptcode String
336      */
337     public static String createDebugStatement(String stmnt) {
338         return "dojo.debug(\"" + stmnt + "\");\n";
339     }
340 
341     /**
342      * creates a debug statement and a corresponding value for the debug console
343      *
344      * @param stmnt
345      *            the debug message displayed and given value by the debug
346      *            console
347      * @return javaScriptcode String
348      */
349     public static String createDebugStatement(String stmnt, String value) {
350         return "dojo.debug(\"" + stmnt + ":\");dojo.debug(" + value + ");\n";
351     }
352 
353     /**
354      * helper method which does the proper dojo provide script creation
355      *
356      * @param provided
357      *            the provided class name
358      * @return dojoProvide String
359      */
360     public static String createDojoProvideScript(String provided) {
361 
362         StringBuffer providedBuilder = new StringBuffer(32);
363         providedBuilder.append("dojo.provide('");
364         providedBuilder.append(provided.trim());
365         providedBuilder.append("');");
366 
367         return providedBuilder.toString();
368     }
369 
370     /**
371      * helper method for the proper dojo require script creation
372      *
373      * @param required
374      *            the creation package for the require functionality
375      * @return dojoRequire String
376      */
377     public static String createDojoRequireString(String required) {
378         StringBuffer requiredBuilder = new StringBuffer(32);
379         requiredBuilder.append("dojo.require('");
380         requiredBuilder.append(required.trim());
381         requiredBuilder.append("');");
382 
383         return requiredBuilder.toString();
384     }
385 
386     /**
387      * Request singleton getter method for the djConfig object
388      *
389      * @param context
390      * @return
391      */
392     public static DojoConfig getDjConfigInstance(FacesContext context) {
393 
394         // we wont have a need for a synchronized here, since
395         // we are in a single request cycle anyway
396         // but take care if you use the djconfig in multiple threads!
397         //DojoConfig djConfig = (DojoConfig) ((HttpServletRequest) context.getExternalContext().getRequest()).getAttribute(DJCONFIG_REQ_KEY);
398         DojoConfig djConfig = (DojoConfig) (context.getExternalContext().getRequestMap()).get(DJCONFIG_REQ_KEY);
399 
400         if (djConfig == null) {
401             djConfig = new DojoConfig();
402             //((HttpServletRequest) context.getExternalContext().getRequest()).setAttribute(DJCONFIG_REQ_KEY, djConfig);
403             context.getExternalContext().getRequestMap().put(DJCONFIG_REQ_KEY, djConfig);
404         }
405 
406         return djConfig;
407     }
408 
409     /**
410      * getter for the expanded flat
411      *
412      * @param facesContext
413      * @return
414      */
415     public static Boolean getExpanded(FacesContext facesContext) {
416         // either the development attribute set or a special request key
417         //HttpServletRequest request = (HttpServletRequest) facesContext.getExternalContext().getRequest();
418         //Boolean devStatus = (Boolean) request.getAttribute(INCL_TYPE_REQ_KEY);
419         Boolean devStatus = (Boolean) facesContext.getExternalContext().getRequestMap().get(INCL_TYPE_REQ_KEY);
420         DojoConfig config = getDjConfigInstance(facesContext);
421         if (devStatus == null)
422             devStatus = new Boolean(false);
423         devStatus = new Boolean(devStatus.booleanValue() || (config.getDevelopment() != null && config.getDevelopment().booleanValue()));
424 
425         return devStatus;
426     }
427 
428     /**
429      * Inline script set
430      *
431      * @param context
432      *            standard faces context
433      * @param inlineScript
434      *            key to the inline script
435      * @return true if the inline script already is set
436      */
437     public static boolean isInlineScriptSet(FacesContext context, String inlineScript) {
438 
439         // TODO move this non neutral code into the resource handler
440         //HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
441         Set set = getBodyScriptInfos(context.getExternalContext().getRequestMap());
442 
443         if (!set.contains(inlineScript)) {
444             set.add(inlineScript);
445 
446             return false;
447         }
448 
449         return true;
450     }
451 
452     /**
453      * check if the script with the given inlineScript-name has been added
454      */
455     public static boolean isInlineScriptCheck(FacesContext context, String inlineScript)
456     {
457         // TODO move this non neutral code into the resource handler
458         
459         //HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
460         Set set = getBodyScriptInfos(context.getExternalContext().getRequestMap());
461 
462         return set.contains(inlineScript);
463     }
464 
465     /**
466      * please, instead of using standard dojo taglib mechanisms use this code
467      * for initialisation it will render a clean and proper javascript
468      * initialisation instead. There are issues with ADF and the dojo taglib
469      * mechanisms and also (Alex Russel wont like to hear this) the dojo taglib
470      * initialisation fails on W3C validations. returns the name of the
471      * javascript var for further processing
472      *
473      * @param facesContext
474      *            standard faces context
475      * @param component
476      *            standard component
477      * @param dojoType
478      *            the dojo type of this component
479      * @param paramMap
480      */
481     public static String renderWidgetInitializationCode(FacesContext facesContext, UIComponent component, String dojoType, Map paramMap) throws IOException {
482         ResponseWriter writer = facesContext.getResponseWriter();
483         String clientId = component.getClientId(facesContext);
484         return renderWidgetInitializationCode(writer, component, dojoType, paramMap, clientId, true);
485     }
486 
487     /**
488      * convenience method to render the widget init code automatically
489      * for a given component and a set of attribute names
490      *
491      * @param facesContext
492      * @param component
493      * @param dojoType
494      * @param attributeNames
495      * @return
496      * @throws IOException
497      */
498     public static String renderWidgetInitializationCode(FacesContext facesContext, UIComponent component, String dojoType, String[] attributeNames)
499             throws IOException {
500         Map paramMap = DojoUtils.getAttributeMap(facesContext, attributeNames, component);
501         return renderWidgetInitializationCode(facesContext, component, dojoType, paramMap);
502     }
503 
504     /**
505      * same for a given neutral id...
506      *
507      * @param dojoType
508      * @param paramMap
509      * @param clientId
510      *            the referencing id which the widget has to render to (note the
511      *            id is enforced the uicomponent does nothing in this case!!!!)
512      * @param refId
513      *            if true the refid is set in the dojo javascript init code if
514      *            false no ref is set the false often is needed for containers
515      *            which dynamically generated widgets with no referencing div
516      * @return a string with the name of the javascript variable
517      */
518     public static String renderWidgetInitializationCode(ResponseWriter writer, UIComponent component, String dojoType, Map paramMap, String clientId,
519             boolean refId) throws IOException {
520 
521         writer.startElement(HTML.SCRIPT_ELEM, component);
522         writer.writeAttribute(HTML.TYPE_ATTR, HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT, null);
523 
524         String javascriptVar = (String) paramMap.get("widgetVar");
525         if (StringUtils.isBlank(javascriptVar))
526             javascriptVar = calculateWidgetVarName(clientId);
527 
528         Iterator it = paramMap.entrySet().iterator();
529 
530         writer.write("var ");
531         writer.write(javascriptVar);
532         writer.write(" = ");
533 
534         writer.write("dojo.widget.createWidget(\"");
535         writer.write(dojoType);
536         writer.write("\",");
537 
538         writer.write("{");
539         boolean first = true;
540         while (it.hasNext()) {
541             Entry entry = (Entry) it.next();
542             Object value = entry.getValue();
543             if (value != null) {
544                 if (!first)
545                     writer.write(",");
546                 writer.write(entry.getKey().toString());
547                 writer.write(":");     // only real string values should be within
548                                     // ambersants, dojo req
549                 boolean isString = value instanceof String;
550                 if (isString)
551                 {
552                     if( value.equals("true")
553                         || value.equals("false") )
554                         isString = false;
555                 }
556                 if (isString)
557                     writer.write("'");
558                 writer.write(value.toString());
559                 if (isString)
560                     writer.write("'");
561                 first = false;
562             }
563 
564         }
565         writer.write("}");
566         if (refId) {
567             writer.write(",dojo.byId('");
568             writer.write(clientId);
569             writer.write("')");
570         }
571         writer.write(");");
572 
573         writer.endElement(HTML.SCRIPT_ELEM);
574         return javascriptVar;
575     }
576 
577     /**
578      * helper method to centralize the widget variable name calculation for our
579      * dojo javascript widget init code
580      *
581      * @param clientId
582      *            the client id upon which the var name has to be generated
583      * @return the javascript widget var name for the given client id
584      */
585     public static String calculateWidgetVarName(String clientId) {
586         return clientId.replaceAll("\\:", "_") + "_dojoControl";
587     }
588 
589     /**
590      *
591      * @return
592      */
593     public static String calculateWidgetId(FacesContext context, UIComponent widget) {
594         String widgetVarName = "";
595         if (widget instanceof DojoWidget) {
596             widgetVarName = ((DojoWidget) widget).getWidgetId();
597         }
598         if (StringUtils.isBlank(widgetVarName)) {
599             widgetVarName = calculateWidgetVarName(widget.getClientId(context));
600         }
601         return widgetVarName;
602     }
603 
604 
605     /**
606      *
607      * @return
608      */
609     public static String calculateWidgetVarName(FacesContext context, UIComponent widget) {
610         String widgetVarName = "";
611         if (widget instanceof DojoWidget) {
612             widgetVarName = ((DojoWidget) widget).getWidgetVar();
613         }
614         if (StringUtils.isBlank(widgetVarName)) {
615             widgetVarName = calculateWidgetVarName(widget.getClientId(context));
616         }
617         return widgetVarName;
618     }
619 
620     /**
621      * helper to merge in an external dojo config instance the merge algorithm
622      * is that an existing entry is overwritten if a new config entry is set
623      * make sure that this is not called too often due to the fact that we do
624      * heavy reflection in here
625      *
626      * @param context
627      * @param config
628      */
629     public static void mergeExternalDjConfig(FacesContext context, DojoConfig config) {
630 
631         // we now do the same as beanutils, but for dependency reasons we code
632         // it
633         DojoConfig configSingleton = getDjConfigInstance(context);
634         Class dcConfigClass = DojoConfig.class;
635         Method[] djConfigFieldArr = dcConfigClass.getMethods();
636 
637         for (int cnt = 0; cnt < djConfigFieldArr.length; cnt++) {
638 
639             try {
640                 Method configPropertyField = djConfigFieldArr[cnt];
641                 String methodCore = null;
642 
643                 if ((!configPropertyField.getName().startsWith("getClass") && configPropertyField.getName().startsWith("get"))
644                         || configPropertyField.getName().startsWith("is"))
645                     methodCore = (configPropertyField.getName().startsWith("get")) ? configPropertyField.getName().substring(3) : configPropertyField.getName()
646                             .substring(2);
647 
648                 if (methodCore != null) {
649                     Object val = configPropertyField.invoke(config, null);
650 
651                     if (val != null) {
652                         Class[] setterParams = new Class[1];
653                         setterParams[0] = val.getClass();
654 
655                         Method setMethod = dcConfigClass.getMethod("set" + methodCore, setterParams);
656 
657                         if (setMethod != null) {
658                             Object[] setterArgs = new Object[1];
659                             setterArgs[0] = val;
660                             setMethod.invoke(configSingleton, setterArgs);
661                         }
662                     }
663                 }
664             } catch (IllegalArgumentException e) {
665                 log.error(e);
666             } catch (SecurityException e) {
667                 log.error(e);
668             } catch (IllegalAccessException e) {
669                 log.error(e);
670             } catch (InvocationTargetException e) {
671                 log.error(e);
672             } catch (NoSuchMethodException e) {
673                 log.error(e);
674             }
675         }
676 
677     }
678 
679     /**
680      * if this flag is set to true somewhere before the rendering, the expanded
681      * version is loaded otherwise the nonexpanded version is loaded
682      *
683      * @param facesContext
684      *            context because we again have a full request singleton here
685      * @param expanded
686      *            if set to true the expanded version of the dojo scripts are
687      *            loaded otherwise the non expanded ones are loaded
688      */
689     public static void setExpanded(FacesContext facesContext, Boolean expanded) {
690         //HttpServletRequest request = (HttpServletRequest) facesContext.getExternalContext().getRequest();
691         //request.setAttribute(INCL_TYPE_REQ_KEY, expanded);
692         facesContext.getExternalContext().getRequestMap().put(INCL_TYPE_REQ_KEY, expanded);
693     }
694 
695     /**
696      * helper to write out debug statements this is only a convenience method to
697      * reduce the code bloat
698      *
699      * @param writer
700      * @param stmnt
701      * @return
702      * @throws IOException
703      */
704     public static void writeDebugStatement(ResponseWriter writer, String stmnt) throws IOException {
705         stmnt = createDebugStatement(stmnt);
706         writer.write(stmnt);
707     }
708 
709     /**
710      * dojo namespace definition method allows the definition of a new namespace
711      * within the parameters of the dojo namespacing system
712      *
713      * @param namespace
714      *            the dojo namespace
715      * @param location
716      *            the exaclt script location (can be a relative location)
717      *
718      * @return the namespace script which has to be printed / executed
719      */
720     private static String createNamespaceScript(String namespace, String location) {
721         StringBuffer namespaceBuilder = new StringBuffer(32);
722         namespaceBuilder.append("dojo.hostenv.setModulePrefix('");
723         namespaceBuilder.append(namespace);
724         namespaceBuilder.append("','");
725         namespaceBuilder.append(location);
726         namespaceBuilder.append("');");
727 
728         String namespaceStr = namespaceBuilder.toString();
729 
730         return namespaceStr;
731     }
732 
733     /*
734     private static Set getBodyScriptInfos(HttpServletRequest request) {
735         Set set = (Set) request.getAttribute(BODY_SCRIPT_INFOS_ATTRIBUTE_NAME);
736 
737         if (set == null) {
738             set = new TreeSet();
739             request.setAttribute(BODY_SCRIPT_INFOS_ATTRIBUTE_NAME, set);
740         }
741 
742         return set;
743     }*/
744     
745     private static Set getBodyScriptInfos(Map requestMap) {
746         Set set = (Set) requestMap.get(BODY_SCRIPT_INFOS_ATTRIBUTE_NAME);
747 
748         if (set == null) {
749             set = new TreeSet();
750             requestMap.put(BODY_SCRIPT_INFOS_ATTRIBUTE_NAME, set);
751         }
752 
753         return set;
754     }    
755 
756     /**
757      * helper to write an inline javascript at the exact resource location of
758      * the call
759      *
760      * @param facesContext
761      * @param component
762      * @param script
763      * @throws IOException
764      */
765     private static void writeInlineScript(FacesContext facesContext, UIComponent component, String script) throws IOException {
766         ResponseWriter writer = facesContext.getResponseWriter();
767         writer.startElement(HTML.SCRIPT_ELEM, component);
768         writer.writeAttribute(HTML.TYPE_ATTR, HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT, null);
769         writer.write(script);
770         writer.endElement(HTML.SCRIPT_ELEM);
771     }
772 
773 }