Coverage Report - org.apache.tapestry.contrib.inspector.ShowTemplate
 
Classes in this File Line Coverage Branch Coverage Complexity
ShowTemplate
0%
0/114
0%
0/30
2.231
ShowTemplate$1
0%
0/3
N/A
2.231
 
 1  
 // Copyright 2004, 2005 The Apache Software Foundation
 2  
 //
 3  
 // Licensed under the Apache License, Version 2.0 (the "License");
 4  
 // you may not use this file except in compliance with the License.
 5  
 // You may obtain a copy of the License at
 6  
 //
 7  
 //     http://www.apache.org/licenses/LICENSE-2.0
 8  
 //
 9  
 // Unless required by applicable law or agreed to in writing, software
 10  
 // distributed under the License is distributed on an "AS IS" BASIS,
 11  
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12  
 // See the License for the specific language governing permissions and
 13  
 // limitations under the License.
 14  
 
 15  
 package org.apache.tapestry.contrib.inspector;
 16  
 
 17  
 import java.util.Iterator;
 18  
 import java.util.Map;
 19  
 
 20  
 import org.apache.tapestry.BaseComponent;
 21  
 import org.apache.tapestry.IComponent;
 22  
 import org.apache.tapestry.IDirect;
 23  
 import org.apache.tapestry.IMarkupWriter;
 24  
 import org.apache.tapestry.IRender;
 25  
 import org.apache.tapestry.IRequestCycle;
 26  
 import org.apache.tapestry.engine.DirectServiceParameter;
 27  
 import org.apache.tapestry.engine.IEngineService;
 28  
 import org.apache.tapestry.engine.ILink;
 29  
 import org.apache.tapestry.parse.CloseToken;
 30  
 import org.apache.tapestry.parse.ComponentTemplate;
 31  
 import org.apache.tapestry.parse.LocalizationToken;
 32  
 import org.apache.tapestry.parse.OpenToken;
 33  
 import org.apache.tapestry.parse.TemplateToken;
 34  
 import org.apache.tapestry.parse.TextToken;
 35  
 import org.apache.tapestry.parse.TokenType;
 36  
 import org.apache.tapestry.services.TemplateSource;
 37  
 
 38  
 /**
 39  
  * Component of the {@link Inspector}page used to display the ids and types of all embedded
 40  
  * components.
 41  
  * 
 42  
  * @author Howard Lewis Ship
 43  
  */
 44  
 
 45  0
 public abstract class ShowTemplate extends BaseComponent implements IDirect
 46  
 {
 47  
     /** @since 4.0 */
 48  
     public abstract TemplateSource getTemplateSource();
 49  
 
 50  
     /** @since 4.1 */
 51  
     public abstract IEngineService getDirectService();
 52  
     
 53  
     public boolean getHasTemplate()
 54  
     {
 55  
         Inspector inspector;
 56  
 
 57  0
         inspector = (Inspector) getPage();
 58  
 
 59  
         // Components that inherit from BaseComponent have templates,
 60  
         // others do not.
 61  
 
 62  0
         return inspector.getInspectedComponent() instanceof BaseComponent;
 63  
     }
 64  
 
 65  
     public IRender getTemplateDelegate()
 66  
     {
 67  0
         return new IRender()
 68  0
         {
 69  
             public void render(IMarkupWriter writer, IRequestCycle cycle)
 70  
             {
 71  0
                 writeTemplate(writer, cycle);
 72  0
             }
 73  
         };
 74  
     }
 75  
 
 76  
     /**
 77  
      * Writes the HTML template for the component. When <jwc> tags are written, the id is made
 78  
      * a link (that selects the named component). We use some magic to accomplish this, creating
 79  
      * links as if we were a {@link DirectLink} component, and attributing those links to the
 80  
      * captive {@link DirectLink} component embedded here.
 81  
      */
 82  
 
 83  
     private void writeTemplate(IMarkupWriter writer, IRequestCycle cycle)
 84  
     {
 85  0
         IComponent inspectedComponent = getInspectedComponent();
 86  0
         ComponentTemplate template = null;
 87  
 
 88  
         try
 89  
         {
 90  0
             template = getTemplateSource().getTemplate(cycle, inspectedComponent);
 91  
         }
 92  0
         catch (Exception ex)
 93  
         {
 94  0
             return;
 95  0
         }
 96  
 
 97  0
         writer.begin("pre");
 98  
 
 99  0
         int count = template.getTokenCount();
 100  
 
 101  0
         for (int i = 0; i < count; i++)
 102  
         {
 103  0
             TemplateToken token = template.getToken(i);
 104  0
             TokenType type = token.getType();
 105  
 
 106  0
             if (type == TokenType.TEXT)
 107  
             {
 108  0
                 write(writer, (TextToken) token);
 109  0
                 continue;
 110  
             }
 111  
 
 112  0
             if (type == TokenType.CLOSE)
 113  
             {
 114  0
                 write(writer, (CloseToken) token);
 115  
 
 116  0
                 continue;
 117  
             }
 118  
 
 119  0
             if (token.getType() == TokenType.LOCALIZATION)
 120  
             {
 121  
 
 122  0
                 write(writer, (LocalizationToken) token);
 123  0
                 continue;
 124  
             }
 125  
 
 126  0
             if (token.getType() == TokenType.OPEN)
 127  
             {
 128  0
                 boolean nextIsClose = (i + 1 < count)
 129  
                         && (template.getToken(i + 1).getType() == TokenType.CLOSE);
 130  
 
 131  0
                 write(writer, nextIsClose, (OpenToken) token);
 132  
 
 133  0
                 if (nextIsClose)
 134  0
                     i++;
 135  
 
 136  
                 continue;
 137  
             }
 138  
 
 139  
             // That's all the types known at this time.
 140  
         }
 141  
 
 142  0
         writer.end(); // <pre>
 143  0
     }
 144  
 
 145  
     /** @since 3.0 * */
 146  
 
 147  
     private IComponent getInspectedComponent()
 148  
     {
 149  0
         Inspector page = (Inspector) getPage();
 150  
 
 151  0
         return page.getInspectedComponent();
 152  
     }
 153  
 
 154  
     /** @since 3.0 * */
 155  
 
 156  
     private void write(IMarkupWriter writer, TextToken token)
 157  
     {
 158  
         // Print the section of the template ... print() will
 159  
         // escape and invalid characters as HTML entities. Also,
 160  
         // we show the full stretch of text, not the trimmed version.
 161  
 
 162  0
         writer.print(token.getTemplateDataAsString());
 163  0
     }
 164  
 
 165  
     /** @since 3.0 * */
 166  
 
 167  
     private void write(IMarkupWriter writer, CloseToken token)
 168  
     {
 169  0
         writer.begin("span");
 170  0
         writer.attribute("class", "jwc-tag");
 171  
 
 172  0
         writer.print("</");
 173  0
         writer.print(token.getTag());
 174  0
         writer.print(">");
 175  
 
 176  0
         writer.end(); // <span>
 177  0
     }
 178  
 
 179  
     /** @since 3.0 * */
 180  
 
 181  
     private void write(IMarkupWriter writer, LocalizationToken token)
 182  
     {
 183  0
         IComponent component = getInspectedComponent();
 184  
 
 185  0
         writer.begin("span");
 186  0
         writer.attribute("class", "jwc-tag");
 187  
 
 188  0
         writer.print("<span key=\"");
 189  0
         writer.print(token.getKey());
 190  0
         writer.print('"');
 191  
 
 192  0
         Map attributes = token.getAttributes();
 193  0
         if (attributes != null && !attributes.isEmpty())
 194  
         {
 195  0
             Iterator it = attributes.entrySet().iterator();
 196  0
             while (it.hasNext())
 197  
             {
 198  0
                 Map.Entry entry = (Map.Entry) it.next();
 199  0
                 String attributeName = (String) entry.getKey();
 200  0
                 String attributeValue = (String) entry.getValue();
 201  
 
 202  0
                 writer.print(' ');
 203  0
                 writer.print(attributeName);
 204  0
                 writer.print("=\"");
 205  0
                 writer.print(attributeValue);
 206  0
                 writer.print('"');
 207  
 
 208  0
             }
 209  
         }
 210  
 
 211  0
         writer.print('>');
 212  0
         writer.begin("span");
 213  0
         writer.attribute("class", "localized-string");
 214  
 
 215  0
         writer.print(component.getMessages().getMessage(token.getKey()));
 216  0
         writer.end(); // <span>
 217  
 
 218  0
         writer.print("</span>");
 219  
 
 220  0
         writer.end(); // <span>
 221  0
     }
 222  
 
 223  
     /** @since 3.0 * */
 224  
 
 225  
     private void write(IMarkupWriter writer, boolean nextIsClose, OpenToken token)
 226  
     {
 227  0
         IComponent component = getInspectedComponent();
 228  0
         IEngineService service = getDirectService();
 229  
 
 230  
         // Each id references a component embedded in the inspected component.
 231  
         // Get that component.
 232  
 
 233  0
         String id = token.getId();
 234  0
         IComponent embedded = component.getComponent(id);
 235  0
         Object[] serviceParameters = new Object[]
 236  
         { embedded.getIdPath() };
 237  
 
 238  
         // Build a URL to select that component, as if by the captive
 239  
         // component itself (it's a Direct).
 240  
 
 241  0
         DirectServiceParameter dsp = new DirectServiceParameter(this, serviceParameters);
 242  0
         ILink link = service.getLink(false, dsp);
 243  
 
 244  0
         writer.begin("span");
 245  0
         writer.attribute("class", "jwc-tag");
 246  
 
 247  0
         writer.print("<");
 248  0
         writer.print(token.getTag());
 249  
 
 250  0
         writer.print(" jwcid=\"");
 251  
 
 252  0
         writer.begin("span");
 253  0
         writer.attribute("class", "jwc-id");
 254  
 
 255  0
         writer.begin("a");
 256  0
         writer.attribute("href", link.getURL());
 257  0
         writer.print(id);
 258  
 
 259  0
         writer.end(); // <a>
 260  0
         writer.end(); // <span>
 261  0
         writer.print('"');
 262  
 
 263  0
         Map attributes = token.getAttributesMap();
 264  
 
 265  0
         if (attributes != null)
 266  
         {
 267  0
             Iterator ii = attributes.entrySet().iterator();
 268  
 
 269  0
             while (ii.hasNext())
 270  
             {
 271  0
                 Map.Entry e = (Map.Entry) ii.next();
 272  
 
 273  0
                 String value = (String) e.getValue();
 274  
 
 275  0
                 writer.print(' ');
 276  0
                 writer.print(e.getKey().toString());
 277  0
                 writer.print("=\"");
 278  0
                 writer.print(value);
 279  0
                 writer.print('"');
 280  0
             }
 281  
         }
 282  
 
 283  
         // Collapse an open & close down to a single tag.
 284  
 
 285  0
         if (nextIsClose)
 286  0
             writer.print('/');
 287  
 
 288  0
         writer.print('>');
 289  0
         writer.end(); // <span>
 290  0
     }
 291  
 
 292  
     /**
 293  
      * Invoked when a component id is clicked.
 294  
      */
 295  
 
 296  
     public void trigger(IRequestCycle cycle)
 297  
     {
 298  0
         Inspector inspector = (Inspector) getPage();
 299  
 
 300  0
         String componentId = (String) cycle.getListenerParameters()[0];
 301  0
         inspector.selectComponent(componentId);
 302  
 
 303  0
         IComponent newComponent = inspector.getInspectedComponent();
 304  
 
 305  
         // If the component is not a BaseComponent then it won't have
 306  
         // a template, so switch to the specification view.
 307  
 
 308  0
         if (!(newComponent instanceof BaseComponent))
 309  0
             inspector.setView(View.SPECIFICATION);
 310  0
     }
 311  
 
 312  
     /**
 313  
      * Always returns true.
 314  
      * 
 315  
      * @since 2.3
 316  
      */
 317  
 
 318  
     public boolean isStateful()
 319  
     {
 320  0
         return true;
 321  
     }
 322  
 }