Source Code Cross Referenced for PortalSiteSessionContextImpl.java in  » Portal » jetspeed-2.1.3 » org » apache » jetspeed » portalsite » impl » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Portal » jetspeed 2.1.3 » org.apache.jetspeed.portalsite.impl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         * 
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         * 
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:        package org.apache.jetspeed.portalsite.impl;
0018:
0019:        import java.io.Serializable;
0020:        import java.security.AccessController;
0021:        import java.security.Principal;
0022:        import java.util.HashMap;
0023:        import java.util.Iterator;
0024:        import java.util.List;
0025:        import java.util.Map;
0026:        import java.util.Set;
0027:
0028:        import javax.security.auth.Subject;
0029:        import javax.servlet.http.HttpSessionActivationListener;
0030:        import javax.servlet.http.HttpSessionBindingEvent;
0031:        import javax.servlet.http.HttpSessionBindingListener;
0032:        import javax.servlet.http.HttpSessionEvent;
0033:
0034:        import org.apache.commons.logging.Log;
0035:        import org.apache.commons.logging.LogFactory;
0036:        import org.apache.jetspeed.om.folder.Folder;
0037:        import org.apache.jetspeed.om.page.Page;
0038:        import org.apache.jetspeed.page.PageManager;
0039:        import org.apache.jetspeed.page.PageManagerEventListener;
0040:        import org.apache.jetspeed.page.document.Node;
0041:        import org.apache.jetspeed.page.document.NodeException;
0042:        import org.apache.jetspeed.page.document.NodeNotFoundException;
0043:        import org.apache.jetspeed.page.document.NodeSet;
0044:        import org.apache.jetspeed.portalsite.PortalSiteRequestContext;
0045:        import org.apache.jetspeed.portalsite.PortalSiteSessionContext;
0046:        import org.apache.jetspeed.portalsite.view.SiteView;
0047:        import org.apache.jetspeed.portalsite.view.SiteViewMenuDefinitionLocator;
0048:        import org.apache.jetspeed.profiler.ProfileLocator;
0049:        import org.apache.jetspeed.profiler.ProfileLocatorProperty;
0050:        import org.apache.jetspeed.security.JSSubject;
0051:        import org.apache.jetspeed.security.UserPrincipal;
0052:
0053:        /**
0054:         * This class encapsulates managed session state for and
0055:         * interface to the portal-site component and subscribes
0056:         * to page manager and session events to flush stale state.
0057:         *
0058:         * Note that is object is Serializable since it is designed
0059:         * to be cached in the session. However, because this object
0060:         * is cached only for these two reasons:
0061:         *
0062:         * 1. a performance optimization to reuse SiteViews, and 
0063:         * 2. to hold optional folder page history,
0064:         *
0065:         * this object need not be relocatable between J2 instances.
0066:         * Consequently, all data members are marked transient and
0067:         * the isValid() method is used to test whether this object
0068:         * is a valid context for the session or if it was
0069:         * transferred from another server or the persistent session
0070:         * store and needs to be discarded.
0071:         * 
0072:         * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
0073:         * @version $Id: PortalSiteSessionContextImpl.java 553375 2007-07-05 05:37:00Z taylor $
0074:         */
0075:        public class PortalSiteSessionContextImpl implements 
0076:                PortalSiteSessionContext, PageManagerEventListener,
0077:                HttpSessionActivationListener, HttpSessionBindingListener,
0078:                Serializable {
0079:            /**
0080:             * log - logging instance
0081:             */
0082:            private final static Log log = LogFactory
0083:                    .getLog(PortalSiteSessionContextImpl.class);
0084:
0085:            /**
0086:             * pageManager - PageManager component
0087:             */
0088:            private transient PageManager pageManager;
0089:
0090:            /**
0091:             * profileLocators - map of session profile locators by locator names
0092:             */
0093:            private transient Map profileLocators;
0094:
0095:            /**
0096:             * userPrincipal - session user principal
0097:             */
0098:            private transient String userPrincipal;
0099:
0100:            /**
0101:             * siteView - session site view
0102:             */
0103:            private transient SiteView siteView;
0104:
0105:            /**
0106:             * folderPageHistory - map of last page visited by folder 
0107:             */
0108:            private transient Map folderPageHistory;
0109:
0110:            /**
0111:             * menuDefinitionLocatorCache - cached menu definition locators for
0112:             *                              absolute menus valid for session
0113:             */
0114:            private transient Map menuDefinitionLocatorCache;
0115:
0116:            /**
0117:             * subscribed - flag that indicates whether this context
0118:             *              is subscribed as event listeners
0119:             */
0120:            private transient boolean subscribed;
0121:
0122:            /**
0123:             * stale - flag that indicates whether the state
0124:             *         managed by this context is stale
0125:             */
0126:            private transient boolean stale;
0127:
0128:            /**
0129:             * store which pipeline we are serving
0130:             * 
0131:             */
0132:            private transient String pipeline = "";
0133:
0134:            /**
0135:             * PortalSiteSessionContextImpl - constructor
0136:             *
0137:             * @param pageManager PageManager component instance
0138:             */
0139:            public PortalSiteSessionContextImpl(PageManager pageManager) {
0140:                this .pageManager = pageManager;
0141:                this .pipeline = "";
0142:            }
0143:
0144:            /**
0145:             * newRequestContext - create a new request context instance with fallback and history
0146:             *
0147:             * @param requestProfileLocators request profile locators
0148:             * @return new request context instance
0149:             */
0150:            public PortalSiteRequestContext newRequestContext(
0151:                    Map requestProfileLocators) {
0152:                return new PortalSiteRequestContextImpl(this ,
0153:                        requestProfileLocators, true, true);
0154:            }
0155:
0156:            /**
0157:             * newRequestContext - create a new request context instance with history
0158:             *
0159:             * @param requestProfileLocators request profile locators
0160:             * @param requestFallback flag specifying whether to fallback to root folder
0161:             *                        if locators do not select a page or access is forbidden
0162:             * @return new request context instance
0163:             */
0164:            public PortalSiteRequestContext newRequestContext(
0165:                    Map requestProfileLocators, boolean requestFallback) {
0166:                return new PortalSiteRequestContextImpl(this ,
0167:                        requestProfileLocators, requestFallback, true);
0168:            }
0169:
0170:            /**
0171:             * newRequestContext - create a new request context instance
0172:             *
0173:             * @param requestProfileLocators request profile locators
0174:             * @param requestFallback flag specifying whether to fallback to root folder
0175:             *                        if locators do not select a page or access is forbidden
0176:             * @param useHistory flag indicating whether to use visited page
0177:             *                   history to select default page per site folder
0178:             * @return new request context instance
0179:             */
0180:            public PortalSiteRequestContext newRequestContext(
0181:                    Map requestProfileLocators, boolean requestFallback,
0182:                    boolean useHistory) {
0183:                return new PortalSiteRequestContextImpl(this ,
0184:                        requestProfileLocators, requestFallback, useHistory);
0185:            }
0186:
0187:            /**
0188:             * selectRequestPage - select page proxy for request given profile locators
0189:             *
0190:             * @param requestProfileLocators map of profile locators for request
0191:             * @param requestFallback flag specifying whether to fallback to root folder
0192:             *                        if locators do not select a page or access is forbidden
0193:             * @param useHistory flag indicating whether to use visited page
0194:             *                   history to select default page per site folder
0195:             * @return selected page proxy for request
0196:             * @throws NodeNotFoundException if not found
0197:             * @throws SecurityException if view access not granted
0198:             */
0199:            public Page selectRequestPage(Map requestProfileLocators,
0200:                    boolean requestFallback, boolean useHistory)
0201:                    throws NodeNotFoundException {
0202:                // validate and update session profile locators if modified
0203:                if (updateSessionProfileLocators(requestProfileLocators)) {
0204:                    // extract page request path from the locators
0205:                    String requestPath = Folder.PATH_SEPARATOR;
0206:                    ProfileLocator locator = (ProfileLocator) requestProfileLocators
0207:                            .get(ProfileLocator.PAGE_LOCATOR);
0208:                    if (locator != null) {
0209:                        // use 'page' locator to determine request page by executing
0210:                        // profile locator to determine path
0211:                        requestPath = getRequestPathFromLocator(locator);
0212:                    } else {
0213:                        // 'page' locator unavailable, use first locator since
0214:                        // all locators should have identical request paths, (do
0215:                        // not execute profile locator though to determine path:
0216:                        // simply use the request path)
0217:                        locator = (ProfileLocator) requestProfileLocators
0218:                                .values().iterator().next();
0219:                        requestPath = locator.getRequestPath();
0220:                    }
0221:
0222:                    // attempt to select request page or folder using
0223:                    // profile locators and site view; if fallback
0224:                    // enabled, fallback on missing node or access
0225:                    // exceptions to the parent folders until the root
0226:                    // folder access has been attempted
0227:                    do {
0228:                        // attempt to access requested path
0229:                        Exception fallbackException = null;
0230:                        try {
0231:                            return selectRequestPage(requestPath, useHistory);
0232:                        } catch (NodeNotFoundException nnfe) {
0233:                            if (!requestFallback
0234:                                    || requestPath
0235:                                            .equals(Folder.PATH_SEPARATOR)) {
0236:                                throw nnfe;
0237:                            }
0238:                            fallbackException = nnfe;
0239:                        } catch (SecurityException se) {
0240:                            if (!requestFallback
0241:                                    || requestPath
0242:                                            .equals(Folder.PATH_SEPARATOR)) {
0243:                                throw se;
0244:                            }
0245:                            fallbackException = se;
0246:                        }
0247:
0248:                        // compute fallback request path
0249:                        if (requestFallback
0250:                                && !requestPath.equals(Folder.PATH_SEPARATOR)) {
0251:                            // compute parent folder fallback request path
0252:                            String fallbackRequestPath = requestPath;
0253:                            while (fallbackRequestPath
0254:                                    .endsWith(Folder.PATH_SEPARATOR)) {
0255:                                fallbackRequestPath = fallbackRequestPath
0256:                                        .substring(0, fallbackRequestPath
0257:                                                .length() - 1);
0258:                            }
0259:                            int folderIndex = fallbackRequestPath
0260:                                    .lastIndexOf(Folder.PATH_SEPARATOR);
0261:                            if (folderIndex >= 2) {
0262:                                // fallback to parent folder
0263:                                fallbackRequestPath = fallbackRequestPath
0264:                                        .substring(0, folderIndex);
0265:                            } else {
0266:                                // fallback to root folder
0267:                                fallbackRequestPath = Folder.PATH_SEPARATOR;
0268:                            }
0269:
0270:                            // check fallback path and log fallback operation
0271:                            if (!fallbackRequestPath.equals(requestPath)) {
0272:                                // log fallback
0273:                                if (log.isDebugEnabled()) {
0274:                                    log
0275:                                            .debug(
0276:                                                    "Missing/forbidden page selection fallback: request path="
0277:                                                            + requestPath
0278:                                                            + ", attempting fallback request path="
0279:                                                            + fallbackRequestPath,
0280:                                                    fallbackException);
0281:                                }
0282:
0283:                                // clear all history entries for fallback
0284:                                // request path in advance to make fallback
0285:                                // page selection more predictable
0286:                                Iterator folderIter = getFolderPageHistory()
0287:                                        .keySet().iterator();
0288:                                while (folderIter.hasNext()) {
0289:                                    Folder folder = (Folder) folderIter.next();
0290:                                    if (folder.getUrl().equals(
0291:                                            fallbackRequestPath)) {
0292:                                        folderIter.remove();
0293:                                        break;
0294:                                    }
0295:                                }
0296:
0297:                                // retry requested page access
0298:                                requestPath = fallbackRequestPath;
0299:                            }
0300:                        } else {
0301:                            // fallback attempts complete: no page found for user
0302:                            break;
0303:                        }
0304:                    } while (true);
0305:                }
0306:
0307:                // no request page available
0308:                throw new NodeNotFoundException(
0309:                        "No request page available in site view.");
0310:            }
0311:
0312:            /**
0313:             * getRequestPathFromLocator - execute profile locator to extract
0314:             *                             request path using locator rules; this
0315:             *                             is request specific and is not part of
0316:             *                             the site view
0317:             *
0318:             * @param locator profile locator to execute
0319:             * @return request path from profile locator
0320:             */
0321:            private String getRequestPathFromLocator(ProfileLocator locator) {
0322:                // use profile iterator to process the initial full
0323:                // set of profile locator properties searching for
0324:                // the first non control/navigation, (i.e. page/path),
0325:                // property that will force the request path if
0326:                // non-null; otherwise default to locator request path
0327:                String requestPath = locator.getRequestPath();
0328:                Iterator locatorIter = locator.iterator();
0329:                if (locatorIter.hasNext()) {
0330:                    ProfileLocatorProperty[] properties = (ProfileLocatorProperty[]) locatorIter
0331:                            .next();
0332:                    for (int i = 0; (i < properties.length); i++) {
0333:                        if (!properties[i].isControl()
0334:                                && !properties[i].isNavigation()) {
0335:                            // request page/path property; append to or replace
0336:                            // using locator specified path
0337:                            String path = properties[i].getValue();
0338:                            if (path != null) {
0339:                                // specified page/path to be appended to request path if
0340:                                // relative; otherwise specified page/path to replace
0341:                                // request path
0342:                                if (!path.startsWith(Folder.PATH_SEPARATOR)) {
0343:                                    // strip page from request path if required
0344:                                    // and append page/path to base request path
0345:                                    String basePath = requestPath;
0346:                                    if (basePath == null) {
0347:                                        basePath = Folder.PATH_SEPARATOR;
0348:                                    } else if (basePath
0349:                                            .endsWith(Page.DOCUMENT_TYPE)) {
0350:                                        basePath = basePath
0351:                                                .substring(
0352:                                                        0,
0353:                                                        basePath
0354:                                                                .lastIndexOf(Folder.PATH_SEPARATOR) + 1);
0355:                                    } else if (!basePath
0356:                                            .endsWith(Folder.PATH_SEPARATOR)) {
0357:                                        basePath += Folder.PATH_SEPARATOR;
0358:                                    }
0359:                                    path = basePath + path;
0360:
0361:                                    // make sure path ends in page extension
0362:                                    // if folder not explicitly specified
0363:                                    if (!path.endsWith(Folder.PATH_SEPARATOR)
0364:                                            && !path
0365:                                                    .endsWith(Page.DOCUMENT_TYPE)) {
0366:                                        path += Page.DOCUMENT_TYPE;
0367:                                    }
0368:                                }
0369:
0370:                                // detect profile locator request path modification
0371:                                if (!path.equals(requestPath)) {
0372:                                    // if modified request path ends with default page,
0373:                                    // strip default page from path to allow folder level
0374:                                    // defaulting to take place: locator should not force
0375:                                    // selection of default page when selection of the
0376:                                    // folder is implied by use in locator page/path
0377:                                    if (path.endsWith(Folder.PATH_SEPARATOR
0378:                                            + Folder.FALLBACK_DEFAULT_PAGE)) {
0379:                                        path = path.substring(0, path.length()
0380:                                                - Folder.FALLBACK_DEFAULT_PAGE
0381:                                                        .length());
0382:                                    }
0383:
0384:                                    // log modified page request
0385:                                    if (log.isDebugEnabled()
0386:                                            && !path.equals(requestPath)) {
0387:                                        log
0388:                                                .debug("Request page modified by profile locator: request path="
0389:                                                        + path);
0390:                                    }
0391:                                }
0392:                                return path;
0393:                            }
0394:                        }
0395:                    }
0396:                }
0397:
0398:                // return locator request path
0399:                return requestPath;
0400:            }
0401:
0402:            /**
0403:             * selectRequestPage - select page proxy for request for specified
0404:             *                     path given profile locators and site view
0405:             *                     associated with this context
0406:             *
0407:             * @param requestPath request path
0408:             * @param useHistory flag indicating whether to use visited page
0409:             *                   history to select default page per site folder
0410:             * @return selected page proxy for request
0411:             * @throws NodeNotFoundException if not found
0412:             * @throws SecurityException if view access not granted
0413:             */
0414:            private Page selectRequestPage(String requestPath,
0415:                    boolean useHistory) throws NodeNotFoundException {
0416:                // save access exceptions
0417:                SecurityException accessException = null;
0418:
0419:                // valid SiteView required from session profile locators
0420:                SiteView view = getSiteView();
0421:                if (view != null) {
0422:                    // default request to root folder if not specified
0423:                    if (requestPath == null) {
0424:                        requestPath = Folder.PATH_SEPARATOR;
0425:                    }
0426:
0427:                    // log page request
0428:                    if (log.isDebugEnabled()) {
0429:                        log.debug("Request page: request path=" + requestPath);
0430:                    }
0431:
0432:                    // lookup request path in view for viewable page or folder
0433:                    // nodes; note: directly requested pages/folders may be hidden
0434:                    // or not viewable
0435:                    Node requestNode = null;
0436:                    try {
0437:                        // try page or folder request url
0438:                        requestNode = view.getNodeProxy(requestPath, null,
0439:                                false, false);
0440:                    } catch (NodeNotFoundException nnfe) {
0441:                        // if request path ends with default page, strip from
0442:                        // request url to retry for folder default
0443:                        if (requestPath.endsWith(Folder.PATH_SEPARATOR
0444:                                + Folder.FALLBACK_DEFAULT_PAGE)) {
0445:                            // retry folder request url
0446:                            requestPath = requestPath.substring(0, requestPath
0447:                                    .length()
0448:                                    - Folder.FALLBACK_DEFAULT_PAGE.length());
0449:                            requestNode = view.getNodeProxy(requestPath, null,
0450:                                    true, false);
0451:                        } else {
0452:                            // rethrow original exception
0453:                            throw nnfe;
0454:                        }
0455:                    }
0456:
0457:                    // invoke default page logic to determine folder page
0458:                    if (requestNode instanceof  Folder) {
0459:                        Folder requestFolder = (Folder) requestNode;
0460:
0461:                        // support subfolders specified as default pages;
0462:                        // find highest subfolder with a default page that
0463:                        // specifies a default folder, (not a default page).
0464:                        try {
0465:                            String defaultFolderName = requestFolder
0466:                                    .getDefaultPage();
0467:                            if (defaultFolderName != null) {
0468:                                // do not follow broken default folders
0469:                                Folder defaultRequestFolder = requestFolder;
0470:                                // follow default folders to parent folders
0471:                                while ((defaultRequestFolder != null)
0472:                                        && (defaultFolderName != null)
0473:                                        && defaultFolderName.equals("..")) {
0474:                                    defaultRequestFolder = (Folder) defaultRequestFolder
0475:                                            .getParent();
0476:                                    if (defaultRequestFolder != null) {
0477:                                        defaultFolderName = defaultRequestFolder
0478:                                                .getDefaultPage();
0479:                                    } else {
0480:                                        defaultFolderName = null;
0481:                                    }
0482:                                }
0483:                                // follow default folders to subfolders
0484:                                while ((defaultRequestFolder != null)
0485:                                        && (defaultFolderName != null)
0486:                                        && !defaultFolderName
0487:                                                .endsWith(Page.DOCUMENT_TYPE)
0488:                                        && !defaultFolderName.equals("..")) {
0489:                                    defaultRequestFolder = defaultRequestFolder
0490:                                            .getFolder(defaultFolderName);
0491:                                    defaultFolderName = defaultRequestFolder
0492:                                            .getDefaultPage();
0493:                                }
0494:                                // use default request folder
0495:                                if (defaultRequestFolder != null) {
0496:                                    requestFolder = defaultRequestFolder;
0497:                                }
0498:                            }
0499:                        } catch (NodeException ne) {
0500:                        } catch (NodeNotFoundException nnfe) {
0501:                        } catch (SecurityException se) {
0502:                            requestFolder = null;
0503:                            accessException = se;
0504:                        }
0505:
0506:                        // only request folders with pages can be
0507:                        // selected by request; otherwise, fall back to
0508:                        // parent folders assuming that immediate parents
0509:                        // will have the most appropriate default page
0510:                        NodeSet requestFolderPages = null;
0511:                        if (requestFolder != null) {
0512:                            try {
0513:                                requestFolderPages = requestFolder.getPages();
0514:                                while (((requestFolderPages == null) || requestFolderPages
0515:                                        .isEmpty())
0516:                                        && (requestFolder.getParent() != null)) {
0517:                                    requestFolder = (Folder) requestFolder
0518:                                            .getParent();
0519:                                    requestFolderPages = requestFolder
0520:                                            .getPages();
0521:                                }
0522:                            } catch (NodeException ne) {
0523:                                requestFolderPages = null;
0524:                            } catch (SecurityException se) {
0525:                                requestFolderPages = null;
0526:                                accessException = se;
0527:                            }
0528:                        }
0529:                        if ((requestFolder != null)
0530:                                && (requestFolderPages != null)
0531:                                && !requestFolderPages.isEmpty()) {
0532:                            Page requestPage = null;
0533:
0534:                            // attempt to lookup last visited page by folder proxy
0535:                            // path, (proxies are hashed by their path), contains
0536:                            // test must be performed since identical paths may
0537:                            // occur in multiple site views
0538:                            if (useHistory) {
0539:                                requestPage = (Page) getFolderPageHistory()
0540:                                        .get(requestFolder);
0541:                                if ((requestPage != null)
0542:                                        && requestFolderPages
0543:                                                .contains(requestPage)) {
0544:                                    // log selected request page
0545:                                    if (log.isDebugEnabled()) {
0546:                                        log
0547:                                                .debug("Selected folder historical page: path="
0548:                                                        + view.getManagedPage(
0549:                                                                requestPage)
0550:                                                                .getPath());
0551:                                    }
0552:                                    return requestPage;
0553:                                }
0554:                            }
0555:
0556:                            // get default page for folder proxy if more than one
0557:                            // page is available to choose from
0558:                            if (requestFolderPages.size() > 1) {
0559:                                String defaultPageName = requestFolder
0560:                                        .getDefaultPage();
0561:                                if (defaultPageName == null) {
0562:                                    // use fallback default if default page
0563:                                    // not explicitly specified
0564:                                    defaultPageName = Folder.FALLBACK_DEFAULT_PAGE;
0565:                                }
0566:                                try {
0567:                                    // save last visited non-hidden page for folder proxy
0568:                                    // path, (proxies are hashed by their path), and
0569:                                    // return default page
0570:                                    requestPage = requestFolder
0571:                                            .getPage(defaultPageName);
0572:                                    if (!requestPage.isHidden()) {
0573:                                        getFolderPageHistory().put(
0574:                                                requestFolder, requestPage);
0575:                                    }
0576:
0577:                                    // log selected request page
0578:                                    if (log.isDebugEnabled()) {
0579:                                        log
0580:                                                .debug("Selected folder default page: path="
0581:                                                        + view.getManagedPage(
0582:                                                                requestPage)
0583:                                                                .getPath());
0584:                                    }
0585:                                    return requestPage;
0586:                                } catch (NodeException ne) {
0587:                                } catch (NodeNotFoundException nnfe) {
0588:                                } catch (SecurityException se) {
0589:                                    accessException = se;
0590:                                }
0591:                            }
0592:
0593:                            // default page not available, select first page
0594:                            // proxy in request folder; save last visited
0595:                            // non-hidden page for folder proxy path, (proxies
0596:                            // are hashed by their path), and return default page
0597:                            requestPage = (Page) requestFolderPages.iterator()
0598:                                    .next();
0599:                            if (!requestPage.isHidden()) {
0600:                                getFolderPageHistory().put(requestFolder,
0601:                                        requestPage);
0602:                            }
0603:
0604:                            // log selected request page
0605:                            if (log.isDebugEnabled()) {
0606:                                log.debug("Selected first folder page, path="
0607:                                        + view.getManagedPage(requestPage)
0608:                                                .getPath());
0609:                            }
0610:                            return requestPage;
0611:                        }
0612:                    } else if (requestNode instanceof  Page) {
0613:                        Page requestPage = (Page) requestNode;
0614:
0615:                        // save last visited non-hidden page for folder proxy
0616:                        // path, (proxies are hashed by their path), and
0617:                        // return matched page
0618:                        Folder requestFolder = (Folder) requestPage.getParent();
0619:                        if (!requestPage.isHidden()) {
0620:                            getFolderPageHistory().put(requestFolder,
0621:                                    requestPage);
0622:                        }
0623:
0624:                        // log selected request page
0625:                        if (log.isDebugEnabled()) {
0626:                            log.debug("Selected page, path="
0627:                                    + view.getManagedPage(requestPage)
0628:                                            .getPath());
0629:                        }
0630:                        return requestPage;
0631:                    }
0632:                }
0633:
0634:                // no page matched or accessible
0635:                if (accessException != null) {
0636:                    throw accessException;
0637:                }
0638:                throw new NodeNotFoundException("No page matched "
0639:                        + requestPath + " request in site view.");
0640:            }
0641:
0642:            /**
0643:             * getRequestRootFolder - select root folder proxy for given profile locators
0644:             *
0645:             * @param requestProfileLocators map of profile locators for request
0646:             * @return root folder proxy for request
0647:             * @throws NodeNotFoundException if not found
0648:             * @throws SecurityException if view access not granted
0649:             */
0650:            public Folder getRequestRootFolder(Map requestProfileLocators)
0651:                    throws NodeNotFoundException {
0652:                // validate and update session profile locators if modified
0653:                if (updateSessionProfileLocators(requestProfileLocators)) {
0654:                    // valid site view required from session profile locators
0655:                    SiteView view = getSiteView();
0656:                    if (view != null) {
0657:                        // return root folder proxy from session site view
0658:                        return view.getRootFolderProxy();
0659:                    }
0660:                }
0661:
0662:                // no root folder available
0663:                throw new NodeNotFoundException(
0664:                        "No root folder available in site view.");
0665:            }
0666:
0667:            /**
0668:             * updateSessionProfileLocators - detect modification of and update cached
0669:             *                                session profile locators
0670:             *
0671:             * @param requestProfileLocators map of profile locators for request
0672:             * @return profile locators validation flag
0673:             */
0674:            private boolean updateSessionProfileLocators(
0675:                    Map requestProfileLocators) {
0676:                // request profile locators are required
0677:                if ((requestProfileLocators != null)
0678:                        && !requestProfileLocators.isEmpty()) {
0679:                    // get current user principal; ignore derivative
0680:                    // changes in role and group principals
0681:                    String currentUserPrincipal = null;
0682:                    Subject subject = JSSubject.getSubject(AccessController
0683:                            .getContext());
0684:                    if (subject != null) {
0685:                        Iterator principals = subject.getPrincipals()
0686:                                .iterator();
0687:                        while (principals.hasNext()) {
0688:                            Principal principal = (Principal) principals.next();
0689:                            if (principal instanceof  UserPrincipal) {
0690:                                if (currentUserPrincipal == null) {
0691:                                    currentUserPrincipal = principal.getName();
0692:                                } else {
0693:                                    currentUserPrincipal += "|"
0694:                                            + principal.getName();
0695:                                }
0696:                            }
0697:                        }
0698:                    }
0699:
0700:                    // detect stale session, modification of user
0701:                    // principal, or changed profile locators for
0702:                    // this session context
0703:                    boolean userUpdate = false;
0704:                    boolean locatorsUpdate = false;
0705:                    boolean updated = false;
0706:                    synchronized (this ) {
0707:                        userUpdate = (((userPrincipal == null) && (currentUserPrincipal != null)) || ((userPrincipal != null) && !userPrincipal
0708:                                .equals(currentUserPrincipal)));
0709:                        locatorsUpdate = ((profileLocators == null) || !locatorsEquals(
0710:                                profileLocators, requestProfileLocators));
0711:                        if (stale || userUpdate || locatorsUpdate) {
0712:                            // reset cached session profile locators, view,
0713:                            // folder page history, menu definition locators,
0714:                            // and stale flag
0715:                            clearSessionProfileLocators();
0716:                            profileLocators = requestProfileLocators;
0717:                            userPrincipal = currentUserPrincipal;
0718:                            updated = true;
0719:                        }
0720:                    }
0721:
0722:                    // log session context setup and update
0723:                    if (updated && log.isDebugEnabled()) {
0724:                        StringBuffer debug = new StringBuffer();
0725:                        if (userUpdate) {
0726:                            debug.append("Updated user");
0727:                            if (locatorsUpdate) {
0728:                                debug.append("/locators");
0729:                            }
0730:                            if (stale) {
0731:                                debug.append("/stale");
0732:                            }
0733:                        } else if (locatorsUpdate) {
0734:                            debug.append("Updated locators");
0735:                            if (stale) {
0736:                                debug.append("/stale");
0737:                            }
0738:                        } else {
0739:                            debug.append("Updated stale");
0740:                        }
0741:                        debug.append(" context: user=" + userPrincipal
0742:                                + ", profileLocators=(");
0743:                        if (profileLocators != null) {
0744:                            boolean firstEntry = true;
0745:                            Iterator entriesIter = profileLocators.entrySet()
0746:                                    .iterator();
0747:                            while (entriesIter.hasNext()) {
0748:                                Map.Entry entry = (Map.Entry) entriesIter
0749:                                        .next();
0750:                                String locatorName = (String) entry.getKey();
0751:                                ProfileLocator locator = (ProfileLocator) entry
0752:                                        .getValue();
0753:                                if (!firstEntry) {
0754:                                    debug.append(",");
0755:                                } else {
0756:                                    firstEntry = false;
0757:                                }
0758:                                debug.append(locatorName);
0759:                                debug.append("=");
0760:                                debug.append(locator.toString());
0761:                            }
0762:                        } else {
0763:                            debug.append("null");
0764:                        }
0765:                        debug.append(")");
0766:                        log.debug(debug);
0767:                    }
0768:
0769:                    // return valid
0770:                    return true;
0771:                }
0772:
0773:                // return invalid
0774:                return false;
0775:            }
0776:
0777:            /**
0778:             * clearSessionProfileLocators - clear cache session profile locators
0779:             */
0780:            private void clearSessionProfileLocators() {
0781:                // clear cached session profile locators, view,
0782:                // folder page history, menu definition locators,
0783:                // and stale flag
0784:                synchronized (this ) {
0785:                    profileLocators = null;
0786:                    userPrincipal = null;
0787:                    siteView = null;
0788:                    folderPageHistory = null;
0789:                    if (menuDefinitionLocatorCache != null) {
0790:                        menuDefinitionLocatorCache.clear();
0791:                    }
0792:                    stale = false;
0793:                }
0794:            }
0795:
0796:            /**
0797:             * getSiteView - lookup and/or create site view for
0798:             *               profile locators of this context
0799:             *
0800:             * @return site view instance
0801:             */
0802:            public SiteView getSiteView() {
0803:                if ((siteView == null) && (pageManager != null)
0804:                        && (profileLocators != null)) {
0805:                    // create new site view
0806:                    siteView = new SiteView(pageManager, profileLocators);
0807:
0808:                    // log site view creation
0809:                    if (log.isDebugEnabled()) {
0810:                        log.debug("Created site view: search paths="
0811:                                + siteView.getSearchPathsString());
0812:                    }
0813:                }
0814:                return siteView;
0815:            }
0816:
0817:            /**
0818:             * getPageManager - return PageManager component instance
0819:             *
0820:             * @return PageManager instance
0821:             */
0822:            public PageManager getPageManager() {
0823:                return pageManager;
0824:            }
0825:
0826:            /**
0827:             * isValid - return flag indicating whether this context instance
0828:             *           is valid or if it is stale after being persisted and
0829:             *           reloaded as session state
0830:             *
0831:             * @return valid context status
0832:             */
0833:            public boolean isValid() {
0834:                // existant transient page manager implies valid context 
0835:                return (pageManager != null);
0836:            }
0837:
0838:            /**
0839:             * getProfileLocators - get session profile locators
0840:             */
0841:            public Map getProfileLocators() {
0842:                return profileLocators;
0843:            }
0844:
0845:            /**
0846:             * getStandardMenuNames - get set of available standard menu names
0847:             *  
0848:             * @return menu names set
0849:             */
0850:            public Set getStandardMenuNames() {
0851:                // return standard menu names defined for site view
0852:                SiteView view = getSiteView();
0853:                if (view != null) {
0854:                    return view.getStandardMenuNames();
0855:                }
0856:                return null;
0857:            }
0858:
0859:            /**
0860:             * getMenuDefinitionLocators - get list of node proxy menu definition
0861:             *                             locators from site view
0862:             *
0863:             * @param node site view node proxy
0864:             * @return definition locator list
0865:             */
0866:            public List getMenuDefinitionLocators(Node node) {
0867:                // return menu definition locators for node in site view
0868:                SiteView view = getSiteView();
0869:                if (view != null) {
0870:                    return view.getMenuDefinitionLocators(node);
0871:                }
0872:                return null;
0873:            }
0874:
0875:            /**
0876:             * getMenuDefinitionLocator - get named node proxy menu definition
0877:             *                            locator from site view
0878:             *
0879:             * @param node site view node proxy
0880:             * @param name menu definition name
0881:             * @return menu definition locator
0882:             */
0883:            public SiteViewMenuDefinitionLocator getMenuDefinitionLocator(
0884:                    Node node, String name) {
0885:                // return named menu definition locator for node in site view
0886:                SiteView view = getSiteView();
0887:                if (view != null) {
0888:                    return view.getMenuDefinitionLocator(node, name);
0889:                }
0890:                return null;
0891:            }
0892:
0893:            /**
0894:             * getManagedPage - get concrete page instance from page proxy
0895:             *  
0896:             * @param page page proxy
0897:             * @return managed page
0898:             */
0899:            public Page getManagedPage(Page page) {
0900:                // return managed page in site view
0901:                SiteView view = getSiteView();
0902:                if (view != null) {
0903:                    return view.getManagedPage(page);
0904:                }
0905:                return null;
0906:            }
0907:
0908:            /**
0909:             * getMenuDefinitionLocatorCache - get menu definition locators cache
0910:             *                                 for absolute menus
0911:             *
0912:             * @return menu definition locators cache
0913:             */
0914:            public Map getMenuDefinitionLocatorCache() {
0915:                return menuDefinitionLocatorCache;
0916:            }
0917:
0918:            /**
0919:             * setMenuDefinitionLocatorCache - set menu definition locators cache
0920:             *                                 for absolute menus
0921:             *
0922:             * @return menu definition locators cache
0923:             */
0924:            public void setMenuDefinitionLocatorCache(Map cache) {
0925:                menuDefinitionLocatorCache = cache;
0926:            }
0927:
0928:            /**
0929:             * locatorsEquals - test profile locator maps for equivalence
0930:             *                  ignoring request specifics
0931:             *
0932:             * @param locators0 request profile locator map
0933:             * @param locators1 request profile locator map
0934:             * @return boolean flag indicating equivalence
0935:             */
0936:            private static boolean locatorsEquals(Map locators0, Map locators1) {
0937:                // trivial comparison
0938:                if (locators0 == locators1) {
0939:                    return true;
0940:                }
0941:
0942:                // compare locator map sizes
0943:                if (locators0.size() != locators1.size()) {
0944:                    return false;
0945:                }
0946:
0947:                // compare locator map entries
0948:                Iterator entriesIter = locators0.entrySet().iterator();
0949:                if (entriesIter.hasNext()) {
0950:                    Map.Entry entry = (Map.Entry) entriesIter.next();
0951:                    ProfileLocator locator0 = (ProfileLocator) entry.getValue();
0952:                    ProfileLocator locator1 = (ProfileLocator) locators1
0953:                            .get(entry.getKey());
0954:                    if (locator1 == null) {
0955:                        return false;
0956:                    }
0957:
0958:                    // compare locators using the most specific,
0959:                    // (i.e. first), locator properties array
0960:                    // returned by the locator iterator
0961:                    ProfileLocatorProperty[] properties0 = (ProfileLocatorProperty[]) locator0
0962:                            .iterator().next();
0963:                    ProfileLocatorProperty[] properties1 = (ProfileLocatorProperty[]) locator1
0964:                            .iterator().next();
0965:                    if ((properties0 != null) || (properties1 != null)) {
0966:                        if ((properties0 == null) || (properties1 == null)
0967:                                || (properties0.length != properties1.length)) {
0968:                            return false;
0969:                        }
0970:
0971:                        // compare ordered locator properties
0972:                        for (int i = 0, limit = properties0.length; (i < limit); i++) {
0973:                            // compare property names, control flags, navigation flags,
0974:                            // and values. note: properties values are compared only for
0975:                            // control or navigation properties; otherwise they are
0976:                            // assumed to contain variable request paths that should
0977:                            // be treated as equivalent
0978:                            if (!properties0[i].getName().equals(
0979:                                    properties1[i].getName())
0980:                                    || (properties0[i].isControl() && !properties1[i]
0981:                                            .isControl())
0982:                                    || (properties0[i].isNavigation() && !properties1[i]
0983:                                            .isNavigation())
0984:                                    || ((properties0[i].isControl() || properties0[i]
0985:                                            .isNavigation()) && (((properties0[i]
0986:                                            .getValue() == null) && (properties1[i]
0987:                                            .getValue() != null)) || ((properties0[i]
0988:                                            .getValue() != null) && !properties0[i]
0989:                                            .getValue().equals(
0990:                                                    properties1[i].getValue()))))) {
0991:                                return false;
0992:                            }
0993:                        }
0994:                    }
0995:                }
0996:                return true;
0997:            }
0998:
0999:            /**
1000:             * locatorRequestPath - extract request specific path from profile locator
1001:             *                      using request path from locator
1002:             *
1003:             * @param locator request profile locator
1004:             * @return request path
1005:             
1006:            private static String locatorRequestPath(ProfileLocator locator)
1007:            {
1008:                // use request path in locator as default
1009:                return locatorRequestPath(locator, locator.getRequestPath());
1010:            }
1011:             */
1012:
1013:            /**
1014:             * locatorRequestPath - extract request specific path from profile locator
1015:             *
1016:             * @param locator request profile locator
1017:             * @param requestPath request path
1018:             * @return request path
1019:             
1020:            private static String locatorRequestPath(ProfileLocator locator, String requestPath)
1021:            {
1022:                // search locator using the most specific,
1023:                // (i.e. first), locator properties array
1024:                // returned by the locator iterator and return
1025:                // first valued property that is not a control
1026:                // or navigation type
1027:                ProfileLocatorProperty [] properties = (ProfileLocatorProperty [])locator.iterator().next();
1028:                for (int i = 0, limit = properties.length; (i < limit); i++)
1029:                {
1030:                    if (!properties[i].isControl() && !properties[i].isNavigation() && (properties[i].getValue() != null))
1031:                    {
1032:                        // use specified locator path
1033:                        String locatorPath = properties[i].getValue();
1034:
1035:                        // return specified locatorPath if absolute
1036:                        if (locatorPath.startsWith(Folder.PATH_SEPARATOR))
1037:                        {
1038:                            return locatorPath;
1039:                        }
1040:
1041:                        // page names and relative paths are assumed relative to
1042:                        // request path and that any locator paths with no url
1043:                        // separator should have the page extension appended
1044:                        // get default page if page path null
1045:                        if ((locatorPath.indexOf(Folder.PATH_SEPARATOR) == -1) && !locatorPath.endsWith(Page.DOCUMENT_TYPE))
1046:                        {
1047:                            locatorPath += Page.DOCUMENT_TYPE;
1048:                        }
1049:                    
1050:                        // append locator path to request path, replacing
1051:                        // requested pages and preserving requested folders
1052:                        boolean rootFolderRequest = requestPath.equals(Folder.PATH_SEPARATOR);
1053:                        boolean folderRequest = (!requestPath.endsWith(Page.DOCUMENT_TYPE));
1054:                        int lastSeparatorIndex = requestPath.lastIndexOf(Folder.PATH_SEPARATOR_CHAR);
1055:                        if ((lastSeparatorIndex > 0) && (!folderRequest || requestPath.endsWith(Folder.PATH_SEPARATOR)))
1056:                        {
1057:                            // append locator to request path base path
1058:                            return requestPath.substring(0, lastSeparatorIndex) + Folder.PATH_SEPARATOR + locatorPath;
1059:                        }
1060:                        else if (!rootFolderRequest && folderRequest)
1061:                        {
1062:                            // append locator to request path root folder
1063:                            return requestPath + Folder.PATH_SEPARATOR + locatorPath;
1064:                        }
1065:                        else
1066:                        {
1067:                            // use root folder locator
1068:                            return Folder.PATH_SEPARATOR + locatorPath;
1069:                        }
1070:                    }
1071:                }
1072:                return requestPath;
1073:            }
1074:             */
1075:
1076:            /**
1077:             * newNode - invoked when the definition of a node is
1078:             *           created by the page manager or when the
1079:             *           node creation is otherwise detected
1080:             *
1081:             * @param node new managed node if known
1082:             */
1083:            public void newNode(Node node) {
1084:                // equivalent to node updated event
1085:                updatedNode(node);
1086:            }
1087:
1088:            /**
1089:             * updatedNode - invoked when the definition of a node is
1090:             *               updated by the page manager or when the
1091:             *               node modification is otherwise detected
1092:             *
1093:             * @param node updated managed node if known
1094:             */
1095:            public void updatedNode(Node node) {
1096:                // set stale flag to force session context state reset
1097:                synchronized (this ) {
1098:                    stale = true;
1099:                }
1100:
1101:                // log updated node event
1102:                if (log.isDebugEnabled()) {
1103:                    if (node != null) {
1104:                        log.debug("Page manager update event, (node="
1105:                                + node.getPath()
1106:                                + "): set session context state stale");
1107:                    } else {
1108:                        log
1109:                                .debug("Page manager update event: set session context state stale");
1110:                    }
1111:                }
1112:            }
1113:
1114:            /**
1115:             * removedNode - invoked when the definition of a node is
1116:             *               removed by the page manager or when the
1117:             *               node removal is otherwise detected
1118:             *
1119:             * @param node removed managed node if known
1120:             */
1121:            public void removedNode(Node node) {
1122:                // equivalent to node updated event
1123:                updatedNode(node);
1124:            }
1125:
1126:            /**
1127:             * sessionDidActivate - notification that the session has just
1128:             *                      been activated
1129:             *
1130:             * @param event session activation event
1131:             */
1132:            public void sessionDidActivate(HttpSessionEvent event) {
1133:                // set stale flag to force session context state reset
1134:                synchronized (this ) {
1135:                    stale = true;
1136:                }
1137:
1138:                // log activation event
1139:                if (log.isDebugEnabled()) {
1140:                    log
1141:                            .debug("Session activation event: set session context state stale");
1142:                }
1143:            }
1144:
1145:            /**
1146:             * sessionWillPassivate - notification that the session is about
1147:             *                        to be passivated
1148:             *
1149:             * @param event session activation event
1150:             */
1151:            public void sessionWillPassivate(HttpSessionEvent event) {
1152:                // clear session context state
1153:                clearSessionProfileLocators();
1154:
1155:                // log activation event
1156:                if (log.isDebugEnabled()) {
1157:                    log
1158:                            .debug("Session deactivation event: clear session context state");
1159:                }
1160:            }
1161:
1162:            /**
1163:             * valueBound - notifies this context that it is being bound to
1164:             *              a session and identifies the session
1165:             *
1166:             * @param event session binding event
1167:             */
1168:            public void valueBound(HttpSessionBindingEvent event) {
1169:                // subscribe this session context to page manager events
1170:                synchronized (this ) {
1171:                    if (!subscribed && (pageManager != null)) {
1172:                        pageManager.addListener(this );
1173:                        subscribed = true;
1174:                    }
1175:                }
1176:
1177:                // log binding event
1178:                if (log.isDebugEnabled()) {
1179:                    log
1180:                            .debug("Session bound event: setup page manager listener");
1181:                }
1182:            }
1183:
1184:            /**
1185:             * valueUnbound - notifies this context that it is being unbound
1186:             *                from a session and identifies the session
1187:             *
1188:             * @param event session binding event
1189:             */
1190:            public void valueUnbound(HttpSessionBindingEvent event) {
1191:                // unsubscribe this session context to page manager events
1192:                synchronized (this ) {
1193:                    if (subscribed && (pageManager != null)) {
1194:                        pageManager.removeListener(this );
1195:                        subscribed = false;
1196:                    }
1197:                }
1198:
1199:                // clear session context state
1200:                clearSessionProfileLocators();
1201:
1202:                // log binding event
1203:                if (log.isDebugEnabled()) {
1204:                    log
1205:                            .debug("Session unbound event: clear page manager listener and session context state");
1206:                }
1207:            }
1208:
1209:            private Map getFolderPageHistory() {
1210:                if (folderPageHistory == null) {
1211:                    folderPageHistory = new HashMap();
1212:                }
1213:                return folderPageHistory;
1214:            }
1215:
1216:            public void setPipeline(String pipeline) {
1217:                this .pipeline = pipeline;
1218:            }
1219:
1220:            public String getPipeline() {
1221:                return this.pipeline;
1222:            }
1223:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.