Coverage report

  %line %branch
org.apache.jetspeed.portalsite.impl.PortalSiteSessionContextImpl
0% 
0% 

 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.portalsite.impl;
 18  
 
 19  
 import java.io.Serializable;
 20  
 import java.security.AccessController;
 21  
 import java.security.Principal;
 22  
 import java.util.HashMap;
 23  
 import java.util.Iterator;
 24  
 import java.util.List;
 25  
 import java.util.Map;
 26  
 import java.util.Set;
 27  
 
 28  
 import javax.security.auth.Subject;
 29  
 import javax.servlet.http.HttpSessionActivationListener;
 30  
 import javax.servlet.http.HttpSessionBindingEvent;
 31  
 import javax.servlet.http.HttpSessionBindingListener;
 32  
 import javax.servlet.http.HttpSessionEvent;
 33  
 
 34  
 import org.apache.commons.logging.Log;
 35  
 import org.apache.commons.logging.LogFactory;
 36  
 import org.apache.jetspeed.om.folder.Folder;
 37  
 import org.apache.jetspeed.om.page.Page;
 38  
 import org.apache.jetspeed.page.PageManager;
 39  
 import org.apache.jetspeed.page.PageManagerEventListener;
 40  
 import org.apache.jetspeed.page.document.Node;
 41  
 import org.apache.jetspeed.page.document.NodeException;
 42  
 import org.apache.jetspeed.page.document.NodeNotFoundException;
 43  
 import org.apache.jetspeed.page.document.NodeSet;
 44  
 import org.apache.jetspeed.portalsite.PortalSiteRequestContext;
 45  
 import org.apache.jetspeed.portalsite.PortalSiteSessionContext;
 46  
 import org.apache.jetspeed.portalsite.view.SiteView;
 47  
 import org.apache.jetspeed.portalsite.view.SiteViewMenuDefinitionLocator;
 48  
 import org.apache.jetspeed.profiler.ProfileLocator;
 49  
 import org.apache.jetspeed.profiler.ProfileLocatorProperty;
 50  
 import org.apache.jetspeed.security.JSSubject;
 51  
 import org.apache.jetspeed.security.UserPrincipal;
 52  
 
 53  
 /**
 54  
  * This class encapsulates managed session state for and
 55  
  * interface to the portal-site component and subscribes
 56  
  * to page manager and session events to flush stale state.
 57  
  *
 58  
  * Note that is object is Serializable since it is designed
 59  
  * to be cached in the session. However, because this object
 60  
  * is cached only for these two reasons:
 61  
  *
 62  
  * 1. a performance optimization to reuse SiteViews, and 
 63  
  * 2. to hold optional folder page history,
 64  
  *
 65  
  * this object need not be relocatable between J2 instances.
 66  
  * Consequently, all data members are marked transient and
 67  
  * the isValid() method is used to test whether this object
 68  
  * is a valid context for the session or if it was
 69  
  * transferred from another server or the persistent session
 70  
  * store and needs to be discarded.
 71  
  * 
 72  
  * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
 73  
  * @version $Id: PortalSiteSessionContextImpl.java 553375 2007-07-05 05:37:00Z taylor $
 74  
  */
 75  
 public class PortalSiteSessionContextImpl implements PortalSiteSessionContext, PageManagerEventListener, HttpSessionActivationListener, HttpSessionBindingListener, Serializable
 76  
 {
 77  
     /**
 78  
      * log - logging instance
 79  
      */
 80  0
     private final static Log log = LogFactory.getLog(PortalSiteSessionContextImpl.class);
 81  
 
 82  
     /**
 83  
      * pageManager - PageManager component
 84  
      */
 85  
     private transient PageManager pageManager;
 86  
 
 87  
     /**
 88  
      * profileLocators - map of session profile locators by locator names
 89  
      */
 90  
     private transient Map profileLocators;
 91  
 
 92  
     /**
 93  
      * userPrincipal - session user principal
 94  
      */
 95  
     private transient String userPrincipal;
 96  
 
 97  
     /**
 98  
      * siteView - session site view
 99  
      */
 100  
     private transient SiteView siteView;
 101  
 
 102  
     /**
 103  
      * folderPageHistory - map of last page visited by folder 
 104  
      */
 105  
     private transient Map folderPageHistory;
 106  
 
 107  
     /**
 108  
      * menuDefinitionLocatorCache - cached menu definition locators for
 109  
      *                              absolute menus valid for session
 110  
      */
 111  
     private transient Map menuDefinitionLocatorCache;
 112  
 
 113  
     /**
 114  
      * subscribed - flag that indicates whether this context
 115  
      *              is subscribed as event listeners
 116  
      */
 117  
     private transient boolean subscribed;
 118  
 
 119  
     /**
 120  
      * stale - flag that indicates whether the state
 121  
      *         managed by this context is stale
 122  
      */
 123  
     private transient boolean stale;
 124  
 
 125  
     /**
 126  
      * store which pipeline we are serving
 127  
      * 
 128  
      */
 129  0
     private transient String pipeline = "";
 130  
     
 131  
     /**
 132  
      * PortalSiteSessionContextImpl - constructor
 133  
      *
 134  
      * @param pageManager PageManager component instance
 135  
      */
 136  
     public PortalSiteSessionContextImpl(PageManager pageManager)
 137  0
     {
 138  0
         this.pageManager = pageManager;
 139  0
         this.pipeline = "";
 140  0
     }
 141  
 
 142  
     /**
 143  
      * newRequestContext - create a new request context instance with fallback and history
 144  
      *
 145  
      * @param requestProfileLocators request profile locators
 146  
      * @return new request context instance
 147  
      */
 148  
     public PortalSiteRequestContext newRequestContext(Map requestProfileLocators)
 149  
     {
 150  0
         return new PortalSiteRequestContextImpl(this, requestProfileLocators, true, class="keyword">true);
 151  
     }
 152  
 
 153  
     /**
 154  
      * newRequestContext - create a new request context instance with history
 155  
      *
 156  
      * @param requestProfileLocators request profile locators
 157  
      * @param requestFallback flag specifying whether to fallback to root folder
 158  
      *                        if locators do not select a page or access is forbidden
 159  
      * @return new request context instance
 160  
      */
 161  
     public PortalSiteRequestContext newRequestContext(Map requestProfileLocators, boolean requestFallback)
 162  
     {
 163  0
         return new PortalSiteRequestContextImpl(this, requestProfileLocators, requestFallback, true);
 164  
     }
 165  
 
 166  
     /**
 167  
      * newRequestContext - create a new request context instance
 168  
      *
 169  
      * @param requestProfileLocators request profile locators
 170  
      * @param requestFallback flag specifying whether to fallback to root folder
 171  
      *                        if locators do not select a page or access is forbidden
 172  
      * @param useHistory flag indicating whether to use visited page
 173  
      *                   history to select default page per site folder
 174  
      * @return new request context instance
 175  
      */
 176  
     public PortalSiteRequestContext newRequestContext(Map requestProfileLocators, boolean requestFallback, class="keyword">boolean useHistory)
 177  
     {
 178  0
         return new PortalSiteRequestContextImpl(this, requestProfileLocators, requestFallback, useHistory);
 179  
     }
 180  
 
 181  
     /**
 182  
      * selectRequestPage - select page proxy for request given profile locators
 183  
      *
 184  
      * @param requestProfileLocators map of profile locators for request
 185  
      * @param requestFallback flag specifying whether to fallback to root folder
 186  
      *                        if locators do not select a page or access is forbidden
 187  
      * @param useHistory flag indicating whether to use visited page
 188  
      *                   history to select default page per site folder
 189  
      * @return selected page proxy for request
 190  
      * @throws NodeNotFoundException if not found
 191  
      * @throws SecurityException if view access not granted
 192  
      */
 193  
     public Page selectRequestPage(Map requestProfileLocators, boolean requestFallback, class="keyword">boolean useHistory) throws NodeNotFoundException
 194  
     {
 195  
         // validate and update session profile locators if modified
 196  0
         if (updateSessionProfileLocators(requestProfileLocators))
 197  
         {
 198  
             // extract page request path from the locators
 199  0
             String requestPath = Folder.PATH_SEPARATOR;
 200  0
             ProfileLocator locator = (ProfileLocator)requestProfileLocators.get(ProfileLocator.PAGE_LOCATOR);
 201  0
             if (locator != null)
 202  
             {
 203  
                 // use 'page' locator to determine request page by executing
 204  
                 // profile locator to determine path
 205  0
                 requestPath = getRequestPathFromLocator(locator);
 206  
             }
 207  
             else
 208  
             {
 209  
                 // 'page' locator unavailable, use first locator since
 210  
                 // all locators should have identical request paths, (do
 211  
                 // not execute profile locator though to determine path:
 212  
                 // simply use the request path)
 213  0
                 locator = (ProfileLocator)requestProfileLocators.values().iterator().next();
 214  0
                 requestPath = locator.getRequestPath();
 215  
             }
 216  
             
 217  
             // attempt to select request page or folder using
 218  
             // profile locators and site view; if fallback
 219  
             // enabled, fallback on missing node or access
 220  
             // exceptions to the parent folders until the root
 221  
             // folder access has been attempted
 222  
             do
 223  
             {
 224  
                 // attempt to access requested path
 225  0
                 Exception fallbackException = null;
 226  
                 try
 227  
                 {
 228  0
                     return selectRequestPage(requestPath, useHistory);
 229  
                 }
 230  0
                 catch (NodeNotFoundException nnfe)
 231  
                 {
 232  0
                     if (!requestFallback || requestPath.equals(Folder.PATH_SEPARATOR))
 233  
                     {
 234  0
                         throw nnfe;
 235  
                     }
 236  0
                     fallbackException = nnfe;
 237  
                 }
 238  0
                 catch (SecurityException se)
 239  
                 {
 240  0
                     if (!requestFallback || requestPath.equals(Folder.PATH_SEPARATOR))
 241  
                     {
 242  0
                         throw se;
 243  
                     }
 244  0
                     fallbackException = se;
 245  0
                 }
 246  
 
 247  
                 // compute fallback request path
 248  0
                 if (requestFallback && !requestPath.equals(Folder.PATH_SEPARATOR))
 249  
                 {
 250  
                     // compute parent folder fallback request path
 251  0
                     String fallbackRequestPath = requestPath;
 252  0
                     while (fallbackRequestPath.endsWith(Folder.PATH_SEPARATOR))
 253  
                     {
 254  0
                         fallbackRequestPath = fallbackRequestPath.substring(0, fallbackRequestPath.length()-1);
 255  
                     }
 256  0
                     int folderIndex = fallbackRequestPath.lastIndexOf(Folder.PATH_SEPARATOR);
 257  0
                     if (folderIndex >= 2)
 258  
                     {
 259  
                         // fallback to parent folder
 260  0
                         fallbackRequestPath = fallbackRequestPath.substring(0, folderIndex);
 261  
                     }
 262  
                     else
 263  
                     {
 264  
                         // fallback to root folder
 265  0
                         fallbackRequestPath = Folder.PATH_SEPARATOR;
 266  
                     }
 267  
 
 268  
                     // check fallback path and log fallback operation
 269  0
                     if (!fallbackRequestPath.equals(requestPath))
 270  
                     {
 271  
                         // log fallback
 272  0
                         if (log.isDebugEnabled())
 273  
                         {
 274  0
                             log.debug("Missing/forbidden page selection fallback: request path=" + requestPath + ", attempting fallback request path=" + fallbackRequestPath, fallbackException);
 275  
                         }
 276  
                         
 277  
                         // clear all history entries for fallback
 278  
                         // request path in advance to make fallback
 279  
                         // page selection more predictable
 280  0
                         Iterator folderIter = getFolderPageHistory().keySet().iterator();
 281  0
                         while (folderIter.hasNext())
 282  
                         {
 283  0
                             Folder folder = (Folder)folderIter.next();
 284  0
                             if (folder.getUrl().equals(fallbackRequestPath))
 285  
                             {
 286  0
                                 folderIter.remove();
 287  0
                                 break;
 288  
                             }
 289  0
                         }
 290  
 
 291  
                         // retry requested page access
 292  0
                         requestPath = fallbackRequestPath;
 293  
                     }
 294  
                 }
 295  
                 else
 296  
                 {
 297  
                     // fallback attempts complete: no page found for user
 298  
                     break;
 299  
                 }
 300  
             }
 301  0
             while (true);
 302  
         }
 303  
 
 304  
         // no request page available
 305  0
         throw new NodeNotFoundException("No request page available in site view.");
 306  
     }
 307  
 
 308  
     /**
 309  
      * getRequestPathFromLocator - execute profile locator to extract
 310  
      *                             request path using locator rules; this
 311  
      *                             is request specific and is not part of
 312  
      *                             the site view
 313  
      *
 314  
      * @param locator profile locator to execute
 315  
      * @return request path from profile locator
 316  
      */
 317  
     private String getRequestPathFromLocator(ProfileLocator locator)
 318  
     {
 319  
         // use profile iterator to process the initial full
 320  
         // set of profile locator properties searching for
 321  
         // the first non control/navigation, (i.e. page/path),
 322  
         // property that will force the request path if
 323  
         // non-null; otherwise default to locator request path
 324  0
         String requestPath = locator.getRequestPath();
 325  0
         Iterator locatorIter = locator.iterator();
 326  0
         if (locatorIter.hasNext())
 327  
         {
 328  0
             ProfileLocatorProperty [] properties = (ProfileLocatorProperty []) locatorIter.next();
 329  0
             for (int i = 0; (i < properties.length); i++)
 330  
             {
 331  0
                 if (!properties[i].isControl() && !properties[i].isNavigation())
 332  
                 {
 333  
                     // request page/path property; append to or replace
 334  
                     // using locator specified path
 335  0
                     String path = properties[i].getValue();
 336  0
                     if (path != null)
 337  
                     {
 338  
                         // specified page/path to be appended to request path if
 339  
                         // relative; otherwise specified page/path to replace
 340  
                         // request path
 341  0
                         if (!path.startsWith(Folder.PATH_SEPARATOR))
 342  
                         {
 343  
                             // strip page from request path if required
 344  
                             // and append page/path to base request path
 345  0
                             String basePath = requestPath;
 346  0
                             if (basePath == null)
 347  
                             {
 348  0
                                 basePath = Folder.PATH_SEPARATOR;
 349  
                             }
 350  0
                             else if (basePath.endsWith(Page.DOCUMENT_TYPE))
 351  
                             {
 352  0
                                 basePath = basePath.substring(0, basePath.lastIndexOf(Folder.PATH_SEPARATOR)+1);
 353  
                             }
 354  0
                             else if (!basePath.endsWith(Folder.PATH_SEPARATOR))
 355  
                             {
 356  0
                                 basePath += Folder.PATH_SEPARATOR;
 357  
                             }
 358  0
                             path = basePath + path;
 359  
 
 360  
                             // make sure path ends in page extension
 361  
                             // if folder not explicitly specified
 362  0
                             if (!path.endsWith(Folder.PATH_SEPARATOR) && !path.endsWith(Page.DOCUMENT_TYPE))
 363  
                             {
 364  0
                                 path += Page.DOCUMENT_TYPE;
 365  
                             }
 366  
                         }
 367  
 
 368  
                         // detect profile locator request path modification
 369  0
                         if (!path.equals(requestPath))
 370  
                         {
 371  
                             // if modified request path ends with default page,
 372  
                             // strip default page from path to allow folder level
 373  
                             // defaulting to take place: locator should not force
 374  
                             // selection of default page when selection of the
 375  
                             // folder is implied by use in locator page/path
 376  0
                             if (path.endsWith(Folder.PATH_SEPARATOR + Folder.FALLBACK_DEFAULT_PAGE))
 377  
                             {
 378  0
                                 path = path.substring(0, path.length() - Folder.FALLBACK_DEFAULT_PAGE.length());
 379  
                             }
 380  
                             
 381  
                             // log modified page request
 382  0
                             if (log.isDebugEnabled() && !path.equals(requestPath))
 383  
                             {
 384  0
                                 log.debug("Request page modified by profile locator: request path=" + path);
 385  
                             }
 386  
                         }
 387  0
                         return path;
 388  
                     }
 389  
                 }
 390  
             }
 391  
         }
 392  
 
 393  
         // return locator request path
 394  0
         return requestPath;
 395  
     }
 396  
 
 397  
     /**
 398  
      * selectRequestPage - select page proxy for request for specified
 399  
      *                     path given profile locators and site view
 400  
      *                     associated with this context
 401  
      *
 402  
      * @param requestPath request path
 403  
      * @param useHistory flag indicating whether to use visited page
 404  
      *                   history to select default page per site folder
 405  
      * @return selected page proxy for request
 406  
      * @throws NodeNotFoundException if not found
 407  
      * @throws SecurityException if view access not granted
 408  
      */
 409  
     private Page selectRequestPage(String requestPath, boolean useHistory) throws NodeNotFoundException
 410  
     {
 411  
         // save access exceptions
 412  0
         SecurityException accessException = null;
 413  
 
 414  
         // valid SiteView required from session profile locators
 415  0
         SiteView view = getSiteView();
 416  0
         if (view != null)
 417  
         {
 418  
             // default request to root folder if not specified
 419  0
             if (requestPath == null)
 420  
             {
 421  0
                 requestPath = Folder.PATH_SEPARATOR;
 422  
             }
 423  
             
 424  
             // log page request
 425  0
             if (log.isDebugEnabled())
 426  
             {
 427  0
                 log.debug("Request page: request path=" + requestPath);
 428  
             }
 429  
 
 430  
             // lookup request path in view for viewable page or folder
 431  
             // nodes; note: directly requested pages/folders may be hidden
 432  
             // or not viewable
 433  0
             Node requestNode = null;
 434  
             try
 435  
             {
 436  
                 // try page or folder request url
 437  0
                 requestNode = view.getNodeProxy(requestPath, null, false, false);
 438  
             }
 439  0
             catch (NodeNotFoundException nnfe)
 440  
             {
 441  
                 // if request path ends with default page, strip from
 442  
                 // request url to retry for folder default
 443  0
                 if (requestPath.endsWith(Folder.PATH_SEPARATOR + Folder.FALLBACK_DEFAULT_PAGE))
 444  
                 {
 445  
                     // retry folder request url
 446  0
                     requestPath = requestPath.substring(0, requestPath.length() - Folder.FALLBACK_DEFAULT_PAGE.length());
 447  0
                     requestNode = view.getNodeProxy(requestPath, null, true, false);
 448  
                 }
 449  
                 else
 450  
                 {
 451  
                     // rethrow original exception
 452  0
                     throw nnfe;
 453  
                 }
 454  0
             }
 455  
             
 456  
             // invoke default page logic to determine folder page
 457  0
             if (requestNode instanceof Folder)
 458  
             {
 459  0
                 Folder requestFolder = (Folder)requestNode;
 460  
                 
 461  
                 // support subfolders specified as default pages;
 462  
                 // find highest subfolder with a default page that
 463  
                 // specifies a default folder, (not a default page).
 464  
                 try
 465  
                 {
 466  0
                     String defaultFolderName = requestFolder.getDefaultPage();
 467  0
                     if (defaultFolderName != null)
 468  
                     {
 469  
                         // do not follow broken default folders
 470  0
                         Folder defaultRequestFolder = requestFolder;
 471  
                         // follow default folders to parent folders
 472  0
                         while ((defaultRequestFolder != null) && (defaultFolderName != class="keyword">null) &&
 473  
                                defaultFolderName.equals(".."))
 474  
                         {
 475  0
                             defaultRequestFolder = (Folder)defaultRequestFolder.getParent();
 476  0
                             if (defaultRequestFolder != null)
 477  
                             {
 478  0
                                 defaultFolderName = defaultRequestFolder.getDefaultPage();
 479  
                             }
 480  
                             else
 481  
                             {
 482  0
                                 defaultFolderName = null;
 483  
                             }
 484  
                         }
 485  
                         // follow default folders to subfolders
 486  
                         while ((defaultRequestFolder != null) && (defaultFolderName != class="keyword">null) &&
 487  0
                                !defaultFolderName.endsWith(Page.DOCUMENT_TYPE) && !defaultFolderName.equals(".."))
 488  
                         {
 489  0
                             defaultRequestFolder = defaultRequestFolder.getFolder(defaultFolderName);
 490  0
                             defaultFolderName = defaultRequestFolder.getDefaultPage();
 491  
                         }
 492  
                         // use default request folder
 493  0
                         if (defaultRequestFolder != null)
 494  
                         {
 495  0
                             requestFolder = defaultRequestFolder;
 496  
                         }
 497  
                     }
 498  
                 }
 499  0
                 catch (NodeException ne)
 500  
                 {
 501  
                 }
 502  0
                 catch (NodeNotFoundException nnfe)
 503  
                 {
 504  
                 }
 505  0
                 catch (SecurityException se)
 506  
                 {
 507  0
                     requestFolder = null;
 508  0
                     accessException = se;
 509  0
                 }
 510  
 
 511  
                 // only request folders with pages can be
 512  
                 // selected by request; otherwise, fall back to
 513  
                 // parent folders assuming that immediate parents
 514  
                 // will have the most appropriate default page
 515  0
                 NodeSet requestFolderPages = null;
 516  0
                 if (requestFolder != null)
 517  
                 {
 518  
                     try
 519  
                     {
 520  0
                         requestFolderPages = requestFolder.getPages();
 521  0
                         while (((requestFolderPages == null) || requestFolderPages.isEmpty()) && (requestFolder.getParent() != class="keyword">null))
 522  
                         {
 523  0
                             requestFolder = (Folder)requestFolder.getParent();
 524  0
                             requestFolderPages = requestFolder.getPages();
 525  
                         }
 526  
                     }
 527  0
                     catch (NodeException ne)
 528  
                     {
 529  0
                         requestFolderPages = null;
 530  
                     }
 531  0
                     catch (SecurityException se)
 532  
                     {
 533  0
                         requestFolderPages = null;
 534  0
                         accessException = se;
 535  0
                     }
 536  
                 }
 537  0
                 if ((requestFolder != null) && (requestFolderPages != class="keyword">null) && !requestFolderPages.isEmpty())
 538  
                 {
 539  0
                     Page requestPage = null;
 540  
 
 541  
                     // attempt to lookup last visited page by folder proxy
 542  
                     // path, (proxies are hashed by their path), contains
 543  
                     // test must be performed since identical paths may
 544  
                     // occur in multiple site views
 545  0
                     if (useHistory)
 546  
                     {
 547  0
                         requestPage = (Page)getFolderPageHistory().get(requestFolder);
 548  0
                         if ((requestPage != null) && requestFolderPages.contains(requestPage))
 549  
                         {
 550  
                             // log selected request page
 551  0
                             if (log.isDebugEnabled())
 552  
                             {
 553  0
                                 log.debug("Selected folder historical page: path=" + view.getManagedPage(requestPage).getPath());
 554  
                             }
 555  0
                             return requestPage;
 556  
                         }
 557  
                     }
 558  
                     
 559  
                     // get default page for folder proxy if more than one
 560  
                     // page is available to choose from
 561  0
                     if (requestFolderPages.size() > 1)
 562  
                     {
 563  0
                         String defaultPageName = requestFolder.getDefaultPage();
 564  0
                         if (defaultPageName == null)
 565  
                         {
 566  
                             // use fallback default if default page
 567  
                             // not explicitly specified
 568  0
                             defaultPageName = Folder.FALLBACK_DEFAULT_PAGE;
 569  
                         }
 570  
                         try
 571  
                         {
 572  
                             // save last visited non-hidden page for folder proxy
 573  
                             // path, (proxies are hashed by their path), and
 574  
                             // return default page
 575  0
                             requestPage = requestFolder.getPage(defaultPageName);
 576  0
                             if (!requestPage.isHidden())
 577  
                             {
 578  0
                                 getFolderPageHistory().put(requestFolder, requestPage);
 579  
                             }
 580  
                             
 581  
                             // log selected request page
 582  0
                             if (log.isDebugEnabled())
 583  
                             {
 584  0
                                 log.debug("Selected folder default page: path=" + view.getManagedPage(requestPage).getPath());
 585  
                             }
 586  0
                             return requestPage;
 587  
                         }
 588  0
                         catch (NodeException ne)
 589  
                         {
 590  
                         }
 591  0
                         catch (NodeNotFoundException nnfe)
 592  
                         {
 593  
                         }
 594  0
                         catch (SecurityException se)
 595  
                         {
 596  0
                             accessException = se;
 597  0
                         }
 598  
                     }
 599  
                     
 600  
                     // default page not available, select first page
 601  
                     // proxy in request folder; save last visited
 602  
                     // non-hidden page for folder proxy path, (proxies
 603  
                     // are hashed by their path), and return default page
 604  0
                     requestPage = (Page)requestFolderPages.iterator().next();
 605  0
                     if (!requestPage.isHidden())
 606  
                     {
 607  0
                         getFolderPageHistory().put(requestFolder, requestPage);
 608  
                     }
 609  
 
 610  
                     // log selected request page
 611  0
                     if (log.isDebugEnabled())
 612  
                     {
 613  0
                         log.debug("Selected first folder page, path=" + view.getManagedPage(requestPage).getPath());
 614  
                     }
 615  0
                     return requestPage;
 616  
                 }
 617  0
             }
 618  0
             else if (requestNode instanceof Page)
 619  
             {
 620  0
                 Page requestPage = (Page)requestNode;
 621  
                 
 622  
                 // save last visited non-hidden page for folder proxy
 623  
                 // path, (proxies are hashed by their path), and
 624  
                 // return matched page
 625  0
                 Folder requestFolder = (Folder)requestPage.getParent();
 626  0
                 if (!requestPage.isHidden())
 627  
                 {
 628  0
                 	getFolderPageHistory().put(requestFolder, requestPage);
 629  
                 }
 630  
 
 631  
                 // log selected request page
 632  0
                 if (log.isDebugEnabled())
 633  
                 {
 634  0
                     log.debug("Selected page, path=" + view.getManagedPage(requestPage).getPath());
 635  
                 }
 636  0
                 return requestPage;
 637  
             }
 638  
         }
 639  
             
 640  
         // no page matched or accessible
 641  0
         if (accessException != null)
 642  
         {
 643  0
             throw accessException;
 644  
         }
 645  0
         throw new NodeNotFoundException("No page matched " + requestPath + " request in site view.");
 646  
     }
 647  
     
 648  
     /**
 649  
      * getRequestRootFolder - select root folder proxy for given profile locators
 650  
      *
 651  
      * @param requestProfileLocators map of profile locators for request
 652  
      * @return root folder proxy for request
 653  
      * @throws NodeNotFoundException if not found
 654  
      * @throws SecurityException if view access not granted
 655  
      */
 656  
     public Folder getRequestRootFolder(Map requestProfileLocators) throws NodeNotFoundException
 657  
     {
 658  
         // validate and update session profile locators if modified
 659  0
         if (updateSessionProfileLocators(requestProfileLocators))
 660  
         {
 661  
             // valid site view required from session profile locators
 662  0
             SiteView view = getSiteView();
 663  0
             if (view != null)
 664  
             {
 665  
                 // return root folder proxy from session site view
 666  0
                 return view.getRootFolderProxy();
 667  
             }
 668  
         }
 669  
 
 670  
         // no root folder available
 671  0
         throw new NodeNotFoundException("No root folder available in site view.");
 672  
     }
 673  
 
 674  
     /**
 675  
      * updateSessionProfileLocators - detect modification of and update cached
 676  
      *                                session profile locators
 677  
      *
 678  
      * @param requestProfileLocators map of profile locators for request
 679  
      * @return profile locators validation flag
 680  
      */
 681  
     private boolean updateSessionProfileLocators(Map requestProfileLocators)
 682  
     {
 683  
         // request profile locators are required
 684  0
         if ((requestProfileLocators != null) && !requestProfileLocators.isEmpty())
 685  
         {
 686  
             // get current user principal; ignore derivative
 687  
             // changes in role and group principals
 688  0
             String currentUserPrincipal = null;
 689  0
             Subject subject = JSSubject.getSubject(AccessController.getContext());
 690  0
             if (subject != null)
 691  
             {
 692  0
                 Iterator principals = subject.getPrincipals().iterator();
 693  0
                 while (principals.hasNext())
 694  
                 {
 695  0
                     Principal principal = (Principal) principals.next();
 696  0
                     if (principal instanceof UserPrincipal)
 697  
                     {
 698  0
                         if (currentUserPrincipal == null)
 699  
                         {
 700  0
                             currentUserPrincipal = principal.getName();
 701  
                         }
 702  
                         else
 703  
                         {
 704  0
                             currentUserPrincipal += "|" + principal.getName();
 705  
                         }
 706  
                     }
 707  0
                 }
 708  
             }
 709  
 
 710  
             // detect stale session, modification of user
 711  
             // principal, or changed profile locators for
 712  
             // this session context
 713  0
             boolean userUpdate = false;
 714  0
             boolean locatorsUpdate = false;
 715  0
             boolean updated = false;
 716  0
             synchronized (this)
 717  
             {
 718  0
                 userUpdate = (((userPrincipal == null) && (currentUserPrincipal != class="keyword">null)) ||
 719  
                               ((userPrincipal != null) && !userPrincipal.equals(currentUserPrincipal)));
 720  0
                 locatorsUpdate = ((profileLocators == null) ||
 721  
                                   !locatorsEquals(profileLocators, requestProfileLocators));
 722  0
                 if (stale || userUpdate || locatorsUpdate)
 723  
                 {
 724  
                     // reset cached session profile locators, view,
 725  
                     // folder page history, menu definition locators,
 726  
                     // and stale flag
 727  0
                     clearSessionProfileLocators();
 728  0
                     profileLocators = requestProfileLocators;
 729  0
                     userPrincipal = currentUserPrincipal;
 730  0
                     updated = true;
 731  
                 }
 732  0
             }
 733  
 
 734  
             // log session context setup and update
 735  0
             if (updated && log.isDebugEnabled())
 736  
             {
 737  0
                 StringBuffer debug = new StringBuffer();
 738  0
                 if (userUpdate)
 739  
                 {
 740  0
                     debug.append("Updated user");
 741  0
                     if (locatorsUpdate)
 742  
                     {
 743  0
                         debug.append("/locators");
 744  
                     }
 745  0
                     if (stale)
 746  
                     {
 747  0
                         debug.append("/stale");
 748  
                     }
 749  
                 }
 750  0
                 else if (locatorsUpdate)
 751  
                 {
 752  0
                     debug.append("Updated locators");
 753  0
                     if (stale)
 754  
                     {
 755  0
                         debug.append("/stale");
 756  
                     }
 757  
                 }
 758  
                 else
 759  
                 {
 760  0
                     debug.append("Updated stale");
 761  
                 }
 762  0
                 debug.append(" context: user=" + userPrincipal + ", profileLocators=(");
 763  0
                 if (profileLocators != null)
 764  
                 {
 765  0
                     boolean firstEntry = true;
 766  0
                     Iterator entriesIter = profileLocators.entrySet().iterator();
 767  0
                     while (entriesIter.hasNext())
 768  
                     {
 769  0
                         Map.Entry entry = (Map.Entry)entriesIter.next();
 770  0
                         String locatorName = (String)entry.getKey();
 771  0
                         ProfileLocator locator = (ProfileLocator)entry.getValue();
 772  0
                         if (!firstEntry)
 773  
                         {
 774  0
                             debug.append(",");
 775  
                         }
 776  
                         else
 777  
                         {
 778  0
                             firstEntry = false;
 779  
                         }
 780  0
                         debug.append(locatorName);
 781  0
                         debug.append("=");
 782  0
                         debug.append(locator.toString());
 783  0
                     }
 784  0
                 }
 785  
                 else
 786  
                 {
 787  0
                     debug.append("null");
 788  
                 }
 789  0
                 debug.append(")");
 790  0
                 log.debug(debug);
 791  
             }
 792  
 
 793  
             // return valid
 794  0
             return true;
 795  
         }
 796  
 
 797  
         // return invalid
 798  0
         return false;
 799  
     }
 800  
 
 801  
     /**
 802  
      * clearSessionProfileLocators - clear cache session profile locators
 803  
      */
 804  
     private void clearSessionProfileLocators()
 805  
     {
 806  
         // clear cached session profile locators, view,
 807  
         // folder page history, menu definition locators,
 808  
         // and stale flag
 809  0
         synchronized (this)
 810  
         {
 811  0
             profileLocators = null;
 812  0
             userPrincipal = null;
 813  0
             siteView = null;
 814  0
             folderPageHistory = null;
 815  0
             if (menuDefinitionLocatorCache != null)
 816  
             {
 817  0
                 menuDefinitionLocatorCache.clear();
 818  
             }
 819  0
             stale = false;
 820  0
         }
 821  0
     }
 822  
 
 823  
     /**
 824  
      * getSiteView - lookup and/or create site view for
 825  
      *               profile locators of this context
 826  
      *
 827  
      * @return site view instance
 828  
      */
 829  
     public SiteView getSiteView()
 830  
     {
 831  0
         if ((siteView == null) && (pageManager != class="keyword">null) && (profileLocators != class="keyword">null))
 832  
         {
 833  
             // create new site view
 834  0
             siteView = new SiteView(pageManager, profileLocators);
 835  
 
 836  
             // log site view creation
 837  0
             if (log.isDebugEnabled())
 838  
             {
 839  0
                 log.debug("Created site view: search paths=" + siteView.getSearchPathsString());
 840  
             }
 841  
         }
 842  0
         return siteView;
 843  
     }
 844  
 
 845  
     /**
 846  
      * getPageManager - return PageManager component instance
 847  
      *
 848  
      * @return PageManager instance
 849  
      */
 850  
     public PageManager getPageManager()
 851  
     {
 852  0
         return pageManager;
 853  
     }
 854  
 
 855  
     /**
 856  
      * isValid - return flag indicating whether this context instance
 857  
      *           is valid or if it is stale after being persisted and
 858  
      *           reloaded as session state
 859  
      *
 860  
      * @return valid context status
 861  
      */
 862  
     public boolean isValid()
 863  
     {
 864  
         // existant transient page manager implies valid context 
 865  0
         return (pageManager != null);
 866  
     }
 867  
 
 868  
     /**
 869  
      * getProfileLocators - get session profile locators
 870  
      */
 871  
     public Map getProfileLocators()
 872  
     {
 873  0
         return profileLocators;
 874  
     }
 875  
 
 876  
     /**
 877  
      * getStandardMenuNames - get set of available standard menu names
 878  
      *  
 879  
      * @return menu names set
 880  
      */
 881  
     public Set getStandardMenuNames()
 882  
     {
 883  
         // return standard menu names defined for site view
 884  0
         SiteView view = getSiteView();
 885  0
         if (view != null)
 886  
         {
 887  0
             return view.getStandardMenuNames();
 888  
         }
 889  0
         return null;
 890  
     }
 891  
 
 892  
     /**
 893  
      * getMenuDefinitionLocators - get list of node proxy menu definition
 894  
      *                             locators from site view
 895  
      *
 896  
      * @param node site view node proxy
 897  
      * @return definition locator list
 898  
      */
 899  
     public List getMenuDefinitionLocators(Node node)
 900  
     {
 901  
         // return menu definition locators for node in site view
 902  0
         SiteView view = getSiteView();
 903  0
         if (view != null)
 904  
         {
 905  0
             return view.getMenuDefinitionLocators(node);
 906  
         }
 907  0
         return null;
 908  
     }
 909  
 
 910  
     /**
 911  
      * getMenuDefinitionLocator - get named node proxy menu definition
 912  
      *                            locator from site view
 913  
      *
 914  
      * @param node site view node proxy
 915  
      * @param name menu definition name
 916  
      * @return menu definition locator
 917  
      */
 918  
     public SiteViewMenuDefinitionLocator getMenuDefinitionLocator(Node node, String name)
 919  
     {
 920  
         // return named menu definition locator for node in site view
 921  0
         SiteView view = getSiteView();
 922  0
         if (view != null)
 923  
         {
 924  0
             return view.getMenuDefinitionLocator(node, name);
 925  
         }
 926  0
         return null;
 927  
     }
 928  
 
 929  
     /**
 930  
      * getManagedPage - get concrete page instance from page proxy
 931  
      *  
 932  
      * @param page page proxy
 933  
      * @return managed page
 934  
      */
 935  
     public Page getManagedPage(Page page)
 936  
     {
 937  
         // return managed page in site view
 938  0
         SiteView view = getSiteView();
 939  0
         if (view != null)
 940  
         {
 941  0
             return view.getManagedPage(page);            
 942  
         }
 943  0
         return null;
 944  
     }
 945  
 
 946  
     /**
 947  
      * getMenuDefinitionLocatorCache - get menu definition locators cache
 948  
      *                                 for absolute menus
 949  
      *
 950  
      * @return menu definition locators cache
 951  
      */
 952  
     public Map getMenuDefinitionLocatorCache()
 953  
     {
 954  0
         return menuDefinitionLocatorCache;
 955  
     }
 956  
 
 957  
     /**
 958  
      * setMenuDefinitionLocatorCache - set menu definition locators cache
 959  
      *                                 for absolute menus
 960  
      *
 961  
      * @return menu definition locators cache
 962  
      */
 963  
     public void setMenuDefinitionLocatorCache(Map cache)
 964  
     {
 965  0
         menuDefinitionLocatorCache = cache;
 966  0
     }
 967  
 
 968  
     /**
 969  
      * locatorsEquals - test profile locator maps for equivalence
 970  
      *                  ignoring request specifics
 971  
      *
 972  
      * @param locators0 request profile locator map
 973  
      * @param locators1 request profile locator map
 974  
      * @return boolean flag indicating equivalence
 975  
      */
 976  
     private static boolean locatorsEquals(Map locators0, Map locators1)
 977  
     {
 978  
         // trivial comparison
 979  0
         if (locators0 == locators1)
 980  
         {
 981  0
             return true;
 982  
         }
 983  
 
 984  
         // compare locator map sizes
 985  0
         if (locators0.size() != locators1.size())
 986  
         {
 987  0
             return false;
 988  
         }
 989  
 
 990  
         // compare locator map entries
 991  0
         Iterator entriesIter = locators0.entrySet().iterator();
 992  0
         if (entriesIter.hasNext())
 993  
         {
 994  0
             Map.Entry entry = (Map.Entry)entriesIter.next();
 995  0
             ProfileLocator locator0 = (ProfileLocator)entry.getValue();
 996  0
             ProfileLocator locator1 = (ProfileLocator)locators1.get(entry.getKey());
 997  0
             if (locator1 == null)
 998  
             {
 999  0
                 return false;
 1000  
             }
 1001  
 
 1002  
             // compare locators using the most specific,
 1003  
             // (i.e. first), locator properties array
 1004  
             // returned by the locator iterator
 1005  0
             ProfileLocatorProperty [] properties0 = (ProfileLocatorProperty [])locator0.iterator().next();
 1006  0
             ProfileLocatorProperty [] properties1 = (ProfileLocatorProperty [])locator1.iterator().next();
 1007  0
             if ((properties0 != null) || (properties1 != class="keyword">null))
 1008  
             {
 1009  0
                 if ((properties0 == null) || (properties1 == class="keyword">null) || (properties0.length != properties1.length))
 1010  
                 {
 1011  0
                     return false;
 1012  
                 }
 1013  
                 
 1014  
                 // compare ordered locator properties
 1015  0
                 for (int i = 0, limit = properties0.length; (i < limit); i++)
 1016  
                 {
 1017  
                     // compare property names, control flags, navigation flags,
 1018  
                     // and values. note: properties values are compared only for
 1019  
                     // control or navigation properties; otherwise they are
 1020  
                     // assumed to contain variable request paths that should
 1021  
                     // be treated as equivalent
 1022  0
                     if (!properties0[i].getName().equals(properties1[i].getName()) ||
 1023  
                         (properties0[i].isControl() && !properties1[i].isControl()) ||
 1024  
                         (properties0[i].isNavigation() && !properties1[i].isNavigation()) ||
 1025  
                         ((properties0[i].isControl() || properties0[i].isNavigation()) && 
 1026  
                          (((properties0[i].getValue() == null) && (properties1[i].getValue() != class="keyword">null)) ||
 1027  
                           ((properties0[i].getValue() != null) && !properties0[i].getValue().equals(properties1[i].getValue())))))
 1028  
                     {
 1029  0
                         return false;
 1030  
                     }
 1031  
                 }
 1032  
             }
 1033  
         }
 1034  0
         return true;
 1035  
     }
 1036  
 
 1037  
     /**
 1038  
      * locatorRequestPath - extract request specific path from profile locator
 1039  
      *                      using request path from locator
 1040  
      *
 1041  
      * @param locator request profile locator
 1042  
      * @return request path
 1043  
      
 1044  
     private static String locatorRequestPath(ProfileLocator locator)
 1045  
     {
 1046  
         // use request path in locator as default
 1047  
         return locatorRequestPath(locator, locator.getRequestPath());
 1048  
     }
 1049  
     */
 1050  
 
 1051  
     /**
 1052  
      * locatorRequestPath - extract request specific path from profile locator
 1053  
      *
 1054  
      * @param locator request profile locator
 1055  
      * @param requestPath request path
 1056  
      * @return request path
 1057  
      
 1058  
     private static String locatorRequestPath(ProfileLocator locator, String requestPath)
 1059  
     {
 1060  
         // search locator using the most specific,
 1061  
         // (i.e. first), locator properties array
 1062  
         // returned by the locator iterator and return
 1063  
         // first valued property that is not a control
 1064  
         // or navigation type
 1065  
         ProfileLocatorProperty [] properties = (ProfileLocatorProperty [])locator.iterator().next();
 1066  
         for (int i = 0, limit = properties.length; (i < limit); i++)
 1067  
         {
 1068  
             if (!properties[i].isControl() && !properties[i].isNavigation() && (properties[i].getValue() != null))
 1069  
             {
 1070  
                 // use specified locator path
 1071  
                 String locatorPath = properties[i].getValue();
 1072  
 
 1073  
                 // return specified locatorPath if absolute
 1074  
                 if (locatorPath.startsWith(Folder.PATH_SEPARATOR))
 1075  
                 {
 1076  
                     return locatorPath;
 1077  
                 }
 1078  
 
 1079  
                 // page names and relative paths are assumed relative to
 1080  
                 // request path and that any locator paths with no url
 1081  
                 // separator should have the page extension appended
 1082  
                 // get default page if page path null
 1083  
                 if ((locatorPath.indexOf(Folder.PATH_SEPARATOR) == -1) && !locatorPath.endsWith(Page.DOCUMENT_TYPE))
 1084  
                 {
 1085  
                     locatorPath += Page.DOCUMENT_TYPE;
 1086  
                 }
 1087  
             
 1088  
                 // append locator path to request path, replacing
 1089  
                 // requested pages and preserving requested folders
 1090  
                 boolean rootFolderRequest = requestPath.equals(Folder.PATH_SEPARATOR);
 1091  
                 boolean folderRequest = (!requestPath.endsWith(Page.DOCUMENT_TYPE));
 1092  
                 int lastSeparatorIndex = requestPath.lastIndexOf(Folder.PATH_SEPARATOR_CHAR);
 1093  
                 if ((lastSeparatorIndex > 0) && (!folderRequest || requestPath.endsWith(Folder.PATH_SEPARATOR)))
 1094  
                 {
 1095  
                     // append locator to request path base path
 1096  
                     return requestPath.substring(0, lastSeparatorIndex) + Folder.PATH_SEPARATOR + locatorPath;
 1097  
                 }
 1098  
                 else if (!rootFolderRequest && folderRequest)
 1099  
                 {
 1100  
                     // append locator to request path root folder
 1101  
                     return requestPath + Folder.PATH_SEPARATOR + locatorPath;
 1102  
                 }
 1103  
                 else
 1104  
                 {
 1105  
                     // use root folder locator
 1106  
                     return Folder.PATH_SEPARATOR + locatorPath;
 1107  
                 }
 1108  
             }
 1109  
         }
 1110  
         return requestPath;
 1111  
     }
 1112  
     */
 1113  
 
 1114  
     /**
 1115  
      * newNode - invoked when the definition of a node is
 1116  
      *           created by the page manager or when the
 1117  
      *           node creation is otherwise detected
 1118  
      *
 1119  
      * @param node new managed node if known
 1120  
      */
 1121  
     public void newNode(Node node)
 1122  
     {
 1123  
         // equivalent to node updated event
 1124  0
         updatedNode(node);
 1125  0
     }
 1126  
 
 1127  
     /**
 1128  
      * updatedNode - invoked when the definition of a node is
 1129  
      *               updated by the page manager or when the
 1130  
      *               node modification is otherwise detected
 1131  
      *
 1132  
      * @param node updated managed node if known
 1133  
      */
 1134  
     public void updatedNode(Node node)
 1135  
     {
 1136  
         // set stale flag to force session context state reset
 1137  0
         synchronized (this)
 1138  
         {
 1139  0
             stale = true;
 1140  0
         }
 1141  
 
 1142  
         // log updated node event
 1143  0
         if (log.isDebugEnabled())
 1144  
         {
 1145  0
             if (node != null)
 1146  
             {
 1147  0
                 log.debug("Page manager update event, (node=" + node.getPath() + "): set session context state stale");
 1148  
             }
 1149  
             else
 1150  
             {
 1151  0
                 log.debug("Page manager update event: set session context state stale");
 1152  
             }
 1153  
         }
 1154  0
     }
 1155  
 
 1156  
     /**
 1157  
      * removedNode - invoked when the definition of a node is
 1158  
      *               removed by the page manager or when the
 1159  
      *               node removal is otherwise detected
 1160  
      *
 1161  
      * @param node removed managed node if known
 1162  
      */
 1163  
     public void removedNode(Node node)
 1164  
     {
 1165  
         // equivalent to node updated event
 1166  0
         updatedNode(node);
 1167  0
     }
 1168  
 
 1169  
     /**
 1170  
      * sessionDidActivate - notification that the session has just
 1171  
      *                      been activated
 1172  
      *
 1173  
      * @param event session activation event
 1174  
      */
 1175  
     public void sessionDidActivate(HttpSessionEvent event)
 1176  
     {
 1177  
         // set stale flag to force session context state reset
 1178  0
         synchronized (this)
 1179  
         {
 1180  0
             stale = true;
 1181  0
         }
 1182  
 
 1183  
         // log activation event
 1184  0
         if (log.isDebugEnabled())
 1185  
         {
 1186  0
             log.debug("Session activation event: set session context state stale");
 1187  
         }
 1188  0
     }
 1189  
     
 1190  
     /**
 1191  
      * sessionWillPassivate - notification that the session is about
 1192  
      *                        to be passivated
 1193  
      *
 1194  
      * @param event session activation event
 1195  
      */
 1196  
     public void sessionWillPassivate(HttpSessionEvent event)
 1197  
     {
 1198  
         // clear session context state
 1199  0
         clearSessionProfileLocators();
 1200  
 
 1201  
         // log activation event
 1202  0
         if (log.isDebugEnabled())
 1203  
         {
 1204  0
             log.debug("Session deactivation event: clear session context state");
 1205  
         }
 1206  0
     }
 1207  
 
 1208  
     /**
 1209  
      * valueBound - notifies this context that it is being bound to
 1210  
      *              a session and identifies the session
 1211  
      *
 1212  
      * @param event session binding event
 1213  
      */
 1214  
     public void valueBound(HttpSessionBindingEvent event)
 1215  
     {
 1216  
         // subscribe this session context to page manager events
 1217  0
         synchronized (this)
 1218  
         {
 1219  0
             if (!subscribed && (pageManager != null))
 1220  
             {
 1221  0
                 pageManager.addListener(this);
 1222  0
                 subscribed = true;
 1223  
             }
 1224  0
         }
 1225  
 
 1226  
         // log binding event
 1227  0
         if (log.isDebugEnabled())
 1228  
         {
 1229  0
             log.debug("Session bound event: setup page manager listener");
 1230  
         }
 1231  0
     }
 1232  
     
 1233  
     /**
 1234  
      * valueUnbound - notifies this context that it is being unbound
 1235  
      *                from a session and identifies the session
 1236  
      *
 1237  
      * @param event session binding event
 1238  
      */
 1239  
     public void valueUnbound(HttpSessionBindingEvent event)
 1240  
     {
 1241  
         // unsubscribe this session context to page manager events
 1242  0
         synchronized (this)
 1243  
         {
 1244  0
             if (subscribed && (pageManager != null))
 1245  
             {
 1246  0
                 pageManager.removeListener(this);
 1247  0
                 subscribed = false;
 1248  
             }
 1249  0
         }
 1250  
 
 1251  
         // clear session context state
 1252  0
         clearSessionProfileLocators();
 1253  
 
 1254  
         // log binding event
 1255  0
         if (log.isDebugEnabled())
 1256  
         {
 1257  0
             log.debug("Session unbound event: clear page manager listener and session context state");
 1258  
         }
 1259  0
     }
 1260  
 
 1261  
 	private Map getFolderPageHistory()
 1262  
     {
 1263  0
 		if (folderPageHistory == null)
 1264  
         {
 1265  0
 			folderPageHistory = new HashMap();
 1266  
 		}
 1267  0
 		return folderPageHistory;
 1268  
 	}
 1269  
     
 1270  
     public void setPipeline(String pipeline)
 1271  
     {
 1272  0
         this.pipeline = pipeline;
 1273  0
     }
 1274  
     
 1275  
     public String getPipeline()
 1276  
     {
 1277  0
         return this.pipeline;
 1278  
     }
 1279  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.