Coverage Report - org.apache.tapestry.services.impl.JSONResponseBuilder
 
Classes in this File Line Coverage Branch Coverage Complexity
JSONResponseBuilder
0%
0/102
0%
0/32
1.556
 
 1  
 // Copyright Mar 18, 2006 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  
 package org.apache.tapestry.services.impl;
 15  
 
 16  
 import org.apache.hivemind.Resource;
 17  
 import org.apache.hivemind.util.Defense;
 18  
 import org.apache.tapestry.*;
 19  
 import org.apache.tapestry.asset.AssetFactory;
 20  
 import org.apache.tapestry.engine.NullWriter;
 21  
 import org.apache.tapestry.json.IJSONWriter;
 22  
 import org.apache.tapestry.markup.MarkupWriterSource;
 23  
 import org.apache.tapestry.services.RequestLocaleManager;
 24  
 import org.apache.tapestry.services.ResponseBuilder;
 25  
 import org.apache.tapestry.services.ServiceConstants;
 26  
 import org.apache.tapestry.util.ContentType;
 27  
 import org.apache.tapestry.util.PageRenderSupportImpl;
 28  
 import org.apache.tapestry.web.WebRequest;
 29  
 import org.apache.tapestry.web.WebResponse;
 30  
 
 31  
 import java.io.IOException;
 32  
 import java.io.PrintWriter;
 33  
 import java.util.ArrayList;
 34  
 import java.util.Iterator;
 35  
 import java.util.List;
 36  
 
 37  
 /**
 38  
  * Class that implements JSON responses in tapestry.
 39  
  *
 40  
  * @see <a href="http://json.org">json.org</a>
 41  
  * @author jkuhnert
 42  
  */
 43  
 public class JSONResponseBuilder implements ResponseBuilder
 44  
 {
 45  
     /** Writer that creates JSON output response. */
 46  
     protected IJSONWriter _writer;
 47  
     /** Passed in to bypass normal rendering. */
 48  0
     protected IMarkupWriter _nullWriter = NullWriter.getSharedInstance();
 49  
 
 50  
     /** Parts that will be updated. */
 51  0
     protected List _parts = new ArrayList();
 52  
 
 53  
     protected RequestLocaleManager _localeManager;
 54  
     protected MarkupWriterSource _markupWriterSource;
 55  
 
 56  
     private WebResponse _response;
 57  
 
 58  
     private ContentType _contentType;
 59  
 
 60  
     private final AssetFactory _assetFactory;
 61  
 
 62  
     private final String _namespace;
 63  
 
 64  
     private PageRenderSupportImpl _prs;
 65  
 
 66  
     private IRequestCycle _cycle;
 67  
 
 68  
     /**
 69  
      * Creates a new response builder with the required services it needs
 70  
      * to render the response when {@link #renderResponse(IRequestCycle)} is called.
 71  
      *
 72  
      * @param localeManager
 73  
      *          Used to set the locale on the response.
 74  
      * @param markupWriterSource
 75  
      *          Creates IJSONWriter instance to be used.
 76  
      * @param webResponse
 77  
      *          Web response for output stream.
 78  
      */
 79  
     public JSONResponseBuilder(IRequestCycle cycle, RequestLocaleManager localeManager,
 80  
                                MarkupWriterSource markupWriterSource,
 81  
                                WebResponse webResponse, WebRequest request, AssetFactory assetFactory, String namespace)
 82  0
     {
 83  0
         Defense.notNull(cycle, "cycle");
 84  
 
 85  0
         _cycle = cycle;
 86  0
         _localeManager = localeManager;
 87  0
         _markupWriterSource = markupWriterSource;
 88  0
         _response = webResponse;
 89  
 
 90  
         // Used by PageRenderSupport
 91  
 
 92  0
         _assetFactory = assetFactory;
 93  0
         _namespace = namespace;
 94  
         
 95  0
         _prs = new PageRenderSupportImpl(_assetFactory, _namespace, this, cycle);
 96  0
     }
 97  
 
 98  
     /**
 99  
      *
 100  
      * {@inheritDoc}
 101  
      */
 102  
     public boolean isDynamic()
 103  
     {
 104  0
         return true;
 105  
     }
 106  
 
 107  
     /**
 108  
      * {@inheritDoc}
 109  
      */
 110  
     public void renderResponse(IRequestCycle cycle)
 111  
       throws IOException
 112  
     {
 113  0
         _localeManager.persistLocale();
 114  
 
 115  0
         IPage page = cycle.getPage();
 116  
 
 117  0
         _contentType = page.getResponseContentType();
 118  
 
 119  0
         String encoding = _contentType.getParameter(ENCODING_KEY);
 120  
 
 121  0
         if (encoding == null)
 122  
         {
 123  0
             encoding = cycle.getEngine().getOutputEncoding();
 124  
 
 125  0
             _contentType.setParameter(ENCODING_KEY, encoding);
 126  
         }
 127  
 
 128  0
         if (_writer == null)
 129  
         {
 130  0
             parseParameters(cycle);
 131  
 
 132  0
             PrintWriter printWriter = _response.getPrintWriter(_contentType);
 133  
 
 134  0
             _writer = _markupWriterSource.newJSONWriter(printWriter, _contentType);
 135  
         }
 136  
 
 137  
         // render response
 138  
 
 139  0
         TapestryUtils.storePageRenderSupport(cycle, _prs);
 140  
 
 141  0
         cycle.renderPage(this);
 142  
 
 143  0
         TapestryUtils.removePageRenderSupport(cycle);
 144  
 
 145  0
         flush();
 146  
 
 147  0
         _writer.close();
 148  0
     }
 149  
 
 150  
     public void flush()
 151  
       throws IOException
 152  
     {
 153  
         // Important - causes any cookies stored to properly be written out before the
 154  
         // rest of the response starts being written - see TAPESTRY-825
 155  
 
 156  0
         _writer.flush();
 157  0
     }
 158  
 
 159  
     /**
 160  
      * Grabs the incoming parameters needed for json responses, most notable the
 161  
      * {@link ServiceConstants#UPDATE_PARTS} parameter.
 162  
      *
 163  
      * @param cycle
 164  
      *            The request cycle to parse from
 165  
      */
 166  
     protected void parseParameters(IRequestCycle cycle)
 167  
     {
 168  0
         Object[] updateParts = cycle.getParameters(ServiceConstants.UPDATE_PARTS);
 169  
 
 170  0
         if (updateParts == null)
 171  0
             return;
 172  
 
 173  0
         for(int i = 0; i < updateParts.length; i++)
 174  0
             _parts.add(updateParts[i].toString());
 175  0
     }
 176  
 
 177  
     /**
 178  
      * {@inheritDoc}
 179  
      */
 180  
     public void render(IMarkupWriter writer, IRender render, IRequestCycle cycle)
 181  
     {
 182  0
         if (IJSONRender.class.isInstance(render)
 183  
             && IComponent.class.isInstance(render))
 184  
         {
 185  0
             IJSONRender json = (IJSONRender) render;
 186  0
             IComponent component = (IComponent) render;
 187  
 
 188  0
             if (!contains(component, component.peekClientId()))
 189  
             {
 190  0
                 render.render(_nullWriter, cycle);
 191  0
                 return;
 192  
             }
 193  
 
 194  0
             json.renderComponent(_writer, cycle);
 195  
         }
 196  
 
 197  0
         render.render(_nullWriter, cycle);
 198  0
     }
 199  
 
 200  
     /**
 201  
      * {@inheritDoc}
 202  
      */
 203  
     public void updateComponent(String id)
 204  
     {
 205  0
         if (!_parts.contains(id))
 206  0
             _parts.add(id);
 207  0
     }
 208  
 
 209  
     /**
 210  
      * Determines if the specified component is contained in the 
 211  
      * responses requested update parts.
 212  
      * @param target
 213  
      *          The component to check for.
 214  
      * @return True if the request should capture the components output.
 215  
      */
 216  
     public boolean contains(IComponent target)
 217  
     {
 218  0
         if (target == null)
 219  0
             return false;
 220  
 
 221  0
         String id = target.getClientId();
 222  
 
 223  0
         return contains(target, id);
 224  
     }
 225  
 
 226  
     boolean contains(IComponent target, String id)
 227  
     {
 228  0
         if (_parts.contains(id))
 229  0
             return true;
 230  
 
 231  0
         Iterator it = _cycle.renderStackIterator();
 232  0
         while (it.hasNext())
 233  
         {
 234  0
             IComponent comp = (IComponent)it.next();
 235  0
             String compId = comp.getClientId();
 236  
 
 237  0
             if (comp != target && _parts.contains(compId))
 238  0
                 return true;
 239  0
         }
 240  
 
 241  0
         return false;
 242  
     }
 243  
 
 244  
     /**
 245  
      * {@inheritDoc}
 246  
      */
 247  
     public boolean explicitlyContains(IComponent target)
 248  
     {
 249  0
         if (target == null)
 250  0
             return false;
 251  
 
 252  0
         return _parts.contains(target.getId());
 253  
     }
 254  
 
 255  
     /**
 256  
      * {@inheritDoc}
 257  
      */
 258  
     public IMarkupWriter getWriter()
 259  
     {
 260  0
         return _nullWriter;
 261  
     }
 262  
 
 263  
     /**
 264  
      * {@inheritDoc}
 265  
      */
 266  
     public IMarkupWriter getWriter(String id, String type)
 267  
     {
 268  0
         return _nullWriter;
 269  
     }
 270  
 
 271  
     /**
 272  
      * {@inheritDoc}
 273  
      */
 274  
     public boolean isBodyScriptAllowed(IComponent target)
 275  
     {
 276  0
         return false;
 277  
     }
 278  
 
 279  
     /**
 280  
      * {@inheritDoc}
 281  
      */
 282  
     public boolean isExternalScriptAllowed(IComponent target)
 283  
     {
 284  0
         return false;
 285  
     }
 286  
 
 287  
     /**
 288  
      * {@inheritDoc}
 289  
      */
 290  
     public boolean isInitializationScriptAllowed(IComponent target)
 291  
     {
 292  0
         return false;
 293  
     }
 294  
 
 295  
     /**
 296  
      * {@inheritDoc}
 297  
      */
 298  
     public boolean isImageInitializationAllowed(IComponent target)
 299  
     {
 300  0
         return false;
 301  
     }
 302  
 
 303  
     /**
 304  
      * {@inheritDoc}
 305  
      */
 306  
     public String getPreloadedImageReference(IComponent target, IAsset source)
 307  
     {
 308  0
         return _prs.getPreloadedImageReference(target, source);
 309  
     }
 310  
 
 311  
     /**
 312  
      * {@inheritDoc}
 313  
      */
 314  
     public String getPreloadedImageReference(IComponent target, String url)
 315  
     {
 316  0
         return _prs.getPreloadedImageReference(target, url);
 317  
     }
 318  
 
 319  
     /**
 320  
      * {@inheritDoc}
 321  
      */
 322  
     public String getPreloadedImageReference(String url)
 323  
     {
 324  0
         return _prs.getPreloadedImageReference(url);
 325  
     }
 326  
 
 327  
     /**
 328  
      * {@inheritDoc}
 329  
      */
 330  
     public void addBodyScript(IComponent target, String script)
 331  
     {
 332  0
         _prs.addBodyScript(target, script);
 333  0
     }
 334  
 
 335  
     /**
 336  
      * {@inheritDoc}
 337  
      */
 338  
     public void addBodyScript(String script)
 339  
     {
 340  0
         _prs.addBodyScript(script);
 341  0
     }
 342  
 
 343  
     /**
 344  
      * {@inheritDoc}
 345  
      */
 346  
     public void addExternalScript(IComponent target, Resource resource)
 347  
     {
 348  0
         _prs.addExternalScript(target, resource);
 349  0
     }
 350  
 
 351  
     /**
 352  
      * {@inheritDoc}
 353  
      */
 354  
     public void addExternalScript(Resource resource)
 355  
     {
 356  0
         _prs.addExternalScript(resource);
 357  0
     }
 358  
 
 359  
     /**
 360  
      * {@inheritDoc}
 361  
      */
 362  
     public void addInitializationScript(IComponent target, String script)
 363  
     {
 364  0
         _prs.addInitializationScript(target, script);
 365  0
     }
 366  
 
 367  
     /**
 368  
      * {@inheritDoc}
 369  
      */
 370  
     public void addInitializationScript(String script)
 371  
     {
 372  0
         _prs.addInitializationScript(script);
 373  0
     }
 374  
 
 375  
     public void addScriptAfterInitialization(IComponent target, String script)
 376  
     {
 377  0
         _prs.addScriptAfterInitialization(target, script);
 378  0
     }
 379  
 
 380  
     /**
 381  
      * {@inheritDoc}
 382  
      */
 383  
     public String getUniqueString(String baseValue)
 384  
     {
 385  0
         return _prs.getUniqueString(baseValue);
 386  
     }
 387  
 
 388  
     /**
 389  
      * {@inheritDoc}
 390  
      */
 391  
     public void writeBodyScript(IMarkupWriter writer, IRequestCycle cycle)
 392  
     {
 393  0
         _prs.writeBodyScript(writer, cycle);
 394  0
     }
 395  
 
 396  
     /**
 397  
      * {@inheritDoc}
 398  
      */
 399  
     public void writeInitializationScript(IMarkupWriter writer)
 400  
     {
 401  0
         _prs.writeInitializationScript(writer);
 402  0
     }
 403  
 
 404  
     /**
 405  
      * {@inheritDoc}
 406  
      */
 407  
     public void beginBodyScript(IMarkupWriter writer, IRequestCycle cycle)
 408  
     {
 409  
         // does nothing
 410  0
     }
 411  
 
 412  
     /**
 413  
      * {@inheritDoc}
 414  
      */
 415  
     public void endBodyScript(IMarkupWriter writer, IRequestCycle cycle)
 416  
     {
 417  
         // does nothing
 418  0
     }
 419  
 
 420  
     /**
 421  
      * {@inheritDoc}
 422  
      */
 423  
     public void writeBodyScript(IMarkupWriter writer, String script, IRequestCycle cycle)
 424  
     {
 425  
         // does nothing
 426  0
     }
 427  
 
 428  
     /**
 429  
      * {@inheritDoc}
 430  
      */
 431  
     public void writeExternalScript(IMarkupWriter normalWriter, String url, IRequestCycle cycle)
 432  
     {
 433  
         // does nothing
 434  0
     }
 435  
 
 436  
     /**
 437  
      * {@inheritDoc}
 438  
      */
 439  
     public void writeImageInitializations(IMarkupWriter writer, String script, String preloadName, IRequestCycle cycle)
 440  
     {
 441  
         // does nothing
 442  0
     }
 443  
 
 444  
     /**
 445  
      * {@inheritDoc}
 446  
      */
 447  
     public void writeInitializationScript(IMarkupWriter writer, String script)
 448  
     {
 449  
         // does nothing
 450  0
     }
 451  
 
 452  
     /**
 453  
      * This implementation does nothing.
 454  
      * {@inheritDoc}
 455  
      */
 456  
     public void addStatusMessage(IMarkupWriter normalWriter, String category, String text)
 457  
     {
 458  0
     }
 459  
 }