Coverage Report - org.apache.myfaces.view.facelets.tag.ui.UIDebug
 
Classes in this File Line Coverage Branch Coverage Complexity
UIDebug
0%
0/68
0%
0/20
2.231
UIDebug$1
0%
0/3
N/A
2.231
UIDebug$2
0%
0/2
0%
0/2
2.231
 
 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  
 package org.apache.myfaces.view.facelets.tag.ui;
 20  
 
 21  
 import java.io.IOException;
 22  
 import java.util.ArrayList;
 23  
 import java.util.LinkedHashMap;
 24  
 import java.util.List;
 25  
 import java.util.Map;
 26  
 import java.util.Map.Entry;
 27  
 
 28  
 import javax.faces.component.UIComponent;
 29  
 import javax.faces.component.UIComponentBase;
 30  
 import javax.faces.context.FacesContext;
 31  
 import javax.faces.context.ResponseWriter;
 32  
 import javax.servlet.http.HttpServletResponse;
 33  
 
 34  
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
 35  
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFJspProperty;
 36  
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
 37  
 import org.apache.myfaces.renderkit.ErrorPageWriter;
 38  
 import org.apache.myfaces.view.facelets.util.FastWriter;
 39  
 
 40  
 /**
 41  
  * The debug tag will capture the component tree and variables when it is encoded, 
 42  
  * storing the data for retrieval later. You may launch the debug window at any time 
 43  
  * from your browser by pressing 'CTRL' + 'SHIFT' + 'D' (by default).
 44  
  * 
 45  
  * The debug tag doesn't need to be used with the facelet.DEVELOPMENT parameter.
 46  
  * The best place to put this tag is in your site's main template where it can be 
 47  
  * enabled/disabled across your whole application. 
 48  
  * 
 49  
  * If your application uses multiple windows, you might want to assign different 
 50  
  * hot keys to each one.
 51  
  * 
 52  
  * @author Jacob Hookom
 53  
  * @version $Id$
 54  
  */
 55  
 @JSFComponent(name="ui:debug")
 56  
 @JSFJspProperty(name = "binding", tagExcluded=true)
 57  
 public final class UIDebug extends UIComponentBase
 58  
 {
 59  
     public static final String COMPONENT_TYPE = "facelets.ui.Debug";
 60  
     public static final String COMPONENT_FAMILY = "facelets";
 61  
     public static final String DEFAULT_HOTKEY = "D";
 62  
     
 63  
     private static final String KEY = "facelets.ui.DebugOutput";
 64  
     
 65  0
     private static long nextId = System.currentTimeMillis();
 66  
 
 67  0
     private String _hotkey = DEFAULT_HOTKEY;
 68  
 
 69  
     public UIDebug()
 70  0
     {
 71  0
         setTransient(true);
 72  0
         setRendererType(null);
 73  0
     }
 74  
 
 75  
     public String getFamily()
 76  
     {
 77  0
         return COMPONENT_FAMILY;
 78  
     }
 79  
 
 80  
     public List<UIComponent> getChildren()
 81  
     {
 82  0
         return new ArrayList<UIComponent>()
 83  0
         {
 84  
             public boolean add(UIComponent o)
 85  
             {
 86  0
                 throw new IllegalStateException("<ui:debug> does not support children");
 87  
             }
 88  
 
 89  
             public void add(int index, UIComponent o)
 90  
             {
 91  0
                 throw new IllegalStateException("<ui:debug> does not support children");
 92  
             }
 93  
         };
 94  
     }
 95  
 
 96  
     public void encodeBegin(FacesContext faces) throws IOException
 97  
     {
 98  0
         boolean partialRequest = faces.getPartialViewContext().isPartialRequest();
 99  
         
 100  0
         String actionId = faces.getApplication().getViewHandler()
 101  
                 .getActionURL(faces, faces.getViewRoot().getViewId());
 102  
         
 103  0
         StringBuilder sb = new StringBuilder(512);
 104  0
         sb.append("<script language=\"javascript\" type=\"text/javascript\">\n");
 105  0
         if (!partialRequest)
 106  
         {
 107  0
             sb.append("//<![CDATA[\n");
 108  
         }
 109  0
         sb.append("function faceletsDebug(URL) { day = new Date(); id = day.getTime(); eval(\"page\" + id + \" "
 110  
                   + "= window.open(URL, '\" + id + \"', 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,"
 111  
                   + "resizable=1,width=800,height=600,left = 240,top = 212');\"); };");
 112  0
         sb.append("var faceletsOrigKeyup = document.onkeyup; document.onkeyup = function(e) { "
 113  
                   + "if (window.event) e = window.event; if (String.fromCharCode(e.keyCode) == '"
 114  
                   + this.getHotkey() + "' & e.shiftKey & e.ctrlKey) faceletsDebug('");
 115  0
         sb.append(actionId);
 116  
         
 117  0
         int index = actionId.indexOf('?');
 118  0
         if (index != -1)
 119  
         {
 120  0
             sb.append('&');
 121  
         }
 122  
         else
 123  
         {
 124  0
             sb.append('?');
 125  
         }
 126  0
         sb.append(KEY);
 127  0
         sb.append('=');
 128  0
         sb.append(writeDebugOutput(faces));
 129  0
         sb.append("'); else if (faceletsOrigKeyup) faceletsOrigKeyup(e); };\n");
 130  0
         if (!partialRequest)
 131  
         {
 132  0
             sb.append("//]]>\n");
 133  
         }
 134  0
         sb.append("</script>\n");
 135  
 
 136  0
         ResponseWriter writer = faces.getResponseWriter();
 137  0
         writer.write(sb.toString());
 138  0
     }
 139  
 
 140  
     @SuppressWarnings("unchecked")
 141  
     private static String writeDebugOutput(FacesContext faces) throws IOException
 142  
     {
 143  0
         FastWriter fw = new FastWriter();
 144  0
         ErrorPageWriter.debugHtml(fw, faces);
 145  
 
 146  0
         Map<String, Object> session = faces.getExternalContext().getSessionMap();
 147  0
         Map<String, String> debugs = (Map<String, String>) session.get(KEY);
 148  0
         if (debugs == null)
 149  
         {
 150  0
             debugs = new LinkedHashMap<String, String>()
 151  0
             {
 152  
                 protected boolean removeEldestEntry(Entry<String, String> eldest)
 153  
                 {
 154  0
                     return (this.size() > 5);
 155  
                 }
 156  
             };
 157  
             
 158  0
             session.put(KEY, debugs);
 159  
         }
 160  
         
 161  0
         String id = String.valueOf(nextId++);
 162  
         
 163  0
         debugs.put(id, fw.toString());
 164  
         
 165  0
         return id;
 166  
     }
 167  
 
 168  
     @SuppressWarnings("unchecked")
 169  
     private static String fetchDebugOutput(FacesContext faces, String id)
 170  
     {
 171  0
         Map<String, Object> session = faces.getExternalContext().getSessionMap();
 172  0
         Map<String, String> debugs = (Map<String, String>) session.get(KEY);
 173  0
         if (debugs != null)
 174  
         {
 175  0
             return debugs.get(id);
 176  
         }
 177  
         
 178  0
         return null;
 179  
     }
 180  
 
 181  
     public static boolean debugRequest(FacesContext faces)
 182  
     {
 183  0
         String id = (String) faces.getExternalContext().getRequestParameterMap().get(KEY);
 184  0
         if (id != null)
 185  
         {
 186  0
             Object resp = faces.getExternalContext().getResponse();
 187  0
             if (!faces.getResponseComplete() && resp instanceof HttpServletResponse)
 188  
             {
 189  
                 try
 190  
                 {
 191  0
                     HttpServletResponse httpResp = (HttpServletResponse) resp;
 192  0
                     String page = fetchDebugOutput(faces, id);
 193  0
                     if (page != null)
 194  
                     {
 195  0
                         httpResp.setContentType("text/html");
 196  0
                         httpResp.getWriter().write(page);
 197  
                     }
 198  
                     else
 199  
                     {
 200  0
                         httpResp.setContentType("text/plain");
 201  0
                         httpResp.getWriter().write("No Debug Output Available");
 202  
                     }
 203  0
                     httpResp.flushBuffer();
 204  0
                     faces.responseComplete();
 205  
                 }
 206  0
                 catch (IOException e)
 207  
                 {
 208  0
                     return false;
 209  0
                 }
 210  
                 
 211  0
                 return true;
 212  
             }
 213  
         }
 214  
         
 215  0
         return false;
 216  
     }
 217  
 
 218  
     @JSFProperty(tagExcluded=true)
 219  
     @Override
 220  
     public String getId()
 221  
     {
 222  
         // TODO Auto-generated method stub
 223  0
         return super.getId();
 224  
     }
 225  
 
 226  
     /**
 227  
      * The hot key to use in combination with 'CTRL' + 'SHIFT' to launch the debug window. 
 228  
      * By default, when the debug tag is used, you may launch the debug window with 
 229  
      * 'CTRL' + 'SHIFT' + 'D'. This value cannot be an EL expression.
 230  
      * 
 231  
      * @return
 232  
      */
 233  
     @JSFProperty
 234  
     public String getHotkey()
 235  
     {
 236  0
         return _hotkey;
 237  
     }
 238  
 
 239  
     public void setHotkey(String hotkey)
 240  
     {
 241  0
         _hotkey = (hotkey != null) ? hotkey.toUpperCase() : "";
 242  0
     }
 243  
 }