svnno****@sourc*****
svnno****@sourc*****
2007年 6月 7日 (木) 17:47:41 JST
Revision: 173 http://svn.sourceforge.jp/cgi-bin/viewcvs.cgi?root=pal&view=rev&rev=173 Author: shinsuke Date: 2007-06-07 17:47:40 +0900 (Thu, 07 Jun 2007) Log Message: ----------- added page path pipeline. Modified Paths: -------------- pal-portal/trunk/build.properties pal-portal/trunk/portal/patches/src/webapp/WEB-INF/assembly/pipelines.xml pal-portal/trunk/portal/patches/src/webapp/WEB-INF/web.xml Added Paths: ----------- pal-portal/trunk/portal/files/components/ pal-portal/trunk/portal/files/components/portal/ pal-portal/trunk/portal/files/components/portal/src/ pal-portal/trunk/portal/files/components/portal/src/java/ pal-portal/trunk/portal/files/components/portal/src/java/org/ pal-portal/trunk/portal/files/components/portal/src/java/org/apache/ pal-portal/trunk/portal/files/components/portal/src/java/org/apache/jetspeed/ pal-portal/trunk/portal/files/components/portal/src/java/org/apache/jetspeed/profiler/ pal-portal/trunk/portal/files/components/portal/src/java/org/apache/jetspeed/profiler/impl/ pal-portal/trunk/portal/files/components/portal/src/java/org/apache/jetspeed/profiler/impl/PagePathValveImpl.java -------------- next part -------------- Modified: pal-portal/trunk/build.properties =================================================================== --- pal-portal/trunk/build.properties 2007-06-01 08:04:46 UTC (rev 172) +++ pal-portal/trunk/build.properties 2007-06-07 08:47:40 UTC (rev 173) @@ -182,6 +182,7 @@ src/webapp/WEB-INF/templates/login/html/login.jsp,\ src/webapp/WEB-INF/templates/layout/html/columns/layout.vm,\ src/webapp/WEB-INF/templates/layout/html/maximized/layout.vm,\ +src/webapp/WEB-INF/web.xml,\ src/webapp/decorations/portlet/decorator.vm,\ project.properties,\ jetspeed-api/src/java/org/apache/jetspeed/security/spi/UserSecurityHandler.java,\ Added: pal-portal/trunk/portal/files/components/portal/src/java/org/apache/jetspeed/profiler/impl/PagePathValveImpl.java =================================================================== --- pal-portal/trunk/portal/files/components/portal/src/java/org/apache/jetspeed/profiler/impl/PagePathValveImpl.java 2007-06-01 08:04:46 UTC (rev 172) +++ pal-portal/trunk/portal/files/components/portal/src/java/org/apache/jetspeed/profiler/impl/PagePathValveImpl.java 2007-06-07 08:47:40 UTC (rev 173) @@ -0,0 +1,407 @@ +package org.apache.jetspeed.profiler.impl; + +import java.io.IOException; +import java.security.Principal; +import java.util.HashMap; +import java.util.Map; + +import javax.security.auth.Subject; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.jetspeed.PortalReservedParameters; +import org.apache.jetspeed.decoration.PageActionAccess; +import org.apache.jetspeed.om.folder.Folder; +import org.apache.jetspeed.om.folder.FolderNotFoundException; +import org.apache.jetspeed.om.folder.InvalidFolderException; +import org.apache.jetspeed.om.page.ContentPageImpl; +import org.apache.jetspeed.om.page.Page; +import org.apache.jetspeed.page.PageNotFoundException; +import org.apache.jetspeed.page.document.NodeException; +import org.apache.jetspeed.page.document.NodeNotFoundException; +import org.apache.jetspeed.pipeline.PipelineException; +import org.apache.jetspeed.pipeline.valve.AbstractValve; +import org.apache.jetspeed.pipeline.valve.PageProfilerValve; +import org.apache.jetspeed.pipeline.valve.ValveContext; +import org.apache.jetspeed.portalsite.PortalSite; +import org.apache.jetspeed.portalsite.PortalSiteRequestContext; +import org.apache.jetspeed.portalsite.PortalSiteSessionContext; +import org.apache.jetspeed.profiler.ProfileLocator; +import org.apache.jetspeed.profiler.Profiler; +import org.apache.jetspeed.profiler.ProfilerException; +import org.apache.jetspeed.request.RequestContext; +import org.apache.jetspeed.security.SecurityHelper; +import org.apache.jetspeed.security.UserPrincipal; + +public class PagePathValveImpl extends AbstractValve implements PageProfilerValve +{ + protected Log log = LogFactory.getLog(PagePathValveImpl.class); + + /** + * PORTAL_SITE_REQUEST_CONTEXT_ATTR_KEY - session portal site context attribute key + */ + public static final String PORTAL_SITE_SESSION_CONTEXT_ATTR_KEY = "org.apache.jetspeed.portalsite.PortalSiteSessionContext"; + + /** + * PORTAL_SITE_REQUEST_CONTEXT_ATTR_KEY - request portal site context attribute key + */ + public static final String PORTAL_SITE_REQUEST_CONTEXT_ATTR_KEY = "org.apache.jetspeed.portalsite.PortalSiteRequestContext"; + + /** + * PROFILED_PAGE_CONTEXT_ATTR_KEY - legacy request portal site context attribute key + */ + public static final String PROFILED_PAGE_CONTEXT_ATTR_KEY = "org.apache.jetspeed.profiledPageContext"; + + /** + * session key for storing map of PageActionAccess instances + */ + private static final String PAGE_ACTION_ACCESS_MAP_SESSION_ATTR_KEY = "org.apache.jetspeed.profiler.pageActionAccessMap"; + + /** + * profiler - profiler component + */ + private Profiler profiler; + + /** + * portalSite - portal site component + */ + private PortalSite portalSite; + + /** + * requestFallback - flag indicating whether request should fallback to root folder + * if locators do not select a page or access is forbidden + */ + private boolean requestFallback; + + /** + * useHistory - flag indicating whether to use visited page + * history to select default page per site folder + */ + private boolean useHistory; + + /** + * ProfilerValveImpl - constructor + * + * @param profiler profiler component reference + * @param portalSite portal site component reference + * @param requestFallback flag to enable root folder fallback + * @param useHistory flag to enable selection of last visited folder page + */ + public PagePathValveImpl(Profiler profiler, PortalSite portalSite, boolean requestFallback, boolean useHistory) + { + this.profiler = profiler; + this.portalSite = portalSite; + this.requestFallback = requestFallback; + this.useHistory = useHistory; + } + + /** + * ProfilerValveImpl - constructor + * + * @param profiler profiler component reference + * @param portalSite portal site component reference + * @param requestFallback flag to enable root folder fallback + */ + public PagePathValveImpl(Profiler profiler, PortalSite portalSite, boolean requestFallback) + { + this(profiler, portalSite, requestFallback, true); + } + + /** + * ProfilerValveImpl - constructor + * + * @param profiler profiler component reference + * @param portalSite portal site component reference + */ + public PagePathValveImpl(Profiler profiler, PortalSite portalSite) + { + this(profiler, portalSite, true, true); + } + + /* + * (non-Javadoc) + * + * @see org.apache.jetspeed.pipeline.valve.Valve#invoke(org.apache.jetspeed.request.RequestContext, + * org.apache.jetspeed.pipeline.valve.ValveContext) + */ + public void invoke(RequestContext request, ValveContext context) throws PipelineException + { + try + { + // get profiler locators for request subject/principal using the profiler + Subject subject = request.getSubject(); + if (subject == null) + { + throw new ProfilerException("Missing subject for request: " + request.getPath()); + } + Principal principal = SecurityHelper.getBestPrincipal(subject, UserPrincipal.class); + if (principal == null) + { + throw new ProfilerException("Missing principal for request: " + request.getPath()); + } + + // get request specific profile locators if required + Map locators = null; + String locatorName = (String) request.getAttribute(PROFILE_LOCATOR_REQUEST_ATTR_KEY); + if (locatorName != null) + { + ProfileLocator locator = profiler.getProfile(request, locatorName); + if (locator != null) + { + locators = new HashMap(); + locators.put(ProfileLocator.PAGE_LOCATOR, locator); + } + } + + // get specified or default locators for the current user, + // falling back to global defaults and, if necessary, explicity + // fallback to 'page' profile locators + if (locators == null) + { + locators = profiler.getProfileLocators(request, principal); + } + if (locators.size() == 0) + { + locators = profiler.getDefaultProfileLocators(request); + } + if (locators.size() == 0) + { + locators.put(ProfileLocator.PAGE_LOCATOR, profiler.getProfile(request, ProfileLocator.PAGE_LOCATOR)); + } + + // get profiled page using the profiler, page manager, + // and portal site components + if (locators != null) + { + // get or create portalsite session context; the session + // context maintains the user view of the site and is + // searched against to locate the requested page and + // used to build site menus from its extent; this is + // cached in the session because locators seldom change + // during the session so the session view of the site can + // be cached unless locators do change; if the context + // is invalid, (perhaps because the session was persisted + // and is now being reloaded in a new server), it must be + // replaced with a newly created session context + PortalSiteSessionContext sessionContext = (PortalSiteSessionContext) request + .getSessionAttribute(PORTAL_SITE_SESSION_CONTEXT_ATTR_KEY); + if ((sessionContext == null) || !sessionContext.isValid()) + { + sessionContext = portalSite.newSessionContext(); + request.setSessionAttribute(PORTAL_SITE_SESSION_CONTEXT_ATTR_KEY, sessionContext); + } + + // construct and save a new portalsite request context + // using session context, locators map, fallback, and + // folder page histories; the request context uses the + // locators to initialize or resets the session context if + // locators have changed for this request; the request + // context also acts as a short term request cache for the + // selected page and built menus; however, creating the + // request context here does not select the page or build + // menus: that is done when the request context is + // accessed subsequently + PortalSiteRequestContext requestContext = sessionContext.newRequestContext(locators, requestFallback, useHistory); + request.setAttribute(PORTAL_SITE_REQUEST_CONTEXT_ATTR_KEY, requestContext); + + // additionally save request context under legacy key + // to support existing decorator access + request.setAttribute(PROFILED_PAGE_CONTEXT_ATTR_KEY, requestContext); + + // get profiled page from portalsite request context + // and save profile locators map; accessing the request + // context here and in subsequent valves/decorators + // latently selects the page and builds menus from the + // user site view using the request context locators; + // the managed page accesed here is the raw selected page + // as returned by the PageManager component; accessing + // the managed page here selects the current page for the + // request + // request.setPage(new ContentPageImpl(requestContext.getManagedPage())); + Page page = getRequestedPage(request); + if (page != null) + { + request.setPage(new ContentPageImpl(page)); + } + else + { + request.setPage(new ContentPageImpl(requestContext.getManagedPage())); + } + + request.setProfileLocators(requestContext.getLocators()); + + request.setAttribute(PortalReservedParameters.PAGE_EDIT_ACCESS_ATTRIBUTE, getPageActionAccess(request)); + } + + // continue + context.invokeNext(request); + } + catch (SecurityException se) + { + // fallback to portal root folder/default page if + // no user is available and request path is not + // already attempting to access the root folder; + // this is rarely the case since the anonymous + // user is normally defined unless the default + // security system has been replaced/overridden + if (request.getRequest().getUserPrincipal() == null && request.getPath() != null && !request.getPath().equals("/")) + { + try + { + request.getResponse().sendRedirect(request.getRequest().getContextPath()); + } + catch (IOException ioe) + { + } + return; + } + + // return standard HTTP 403 - FORBIDDEN status + log.error(se.getMessage(), se); + try + { + request.getResponse().sendError(HttpServletResponse.SC_FORBIDDEN, se.getMessage()); + } + catch (IOException ioe) + { + log.error("Failed to invoke HttpServletReponse.sendError: " + ioe.getMessage(), ioe); + } + } + catch (NodeNotFoundException nnfe) + { + // return standard HTTP 404 - NOT FOUND status + log.error(nnfe.getMessage(), nnfe); + try + { + request.getResponse().sendError(HttpServletResponse.SC_NOT_FOUND, nnfe.getMessage()); + } + catch (IOException ioe) + { + log.error("Failed to invoke HttpServletReponse.sendError: " + ioe.getMessage(), ioe); + } + } + catch (Exception e) + { + log.error("Exception in request pipeline: " + e.getMessage(), e); + throw new PipelineException(e.toString(), e); + } + } + + /** + * Returns the <code>PageActionAccess</code> for the current user request. + * @see PageActionAccess + * @param requestContext RequestContext of the current portal request. + * @return PageActionAccess for the current user request. + */ + protected PageActionAccess getPageActionAccess(RequestContext requestContext) + { + Page page = requestContext.getPage(); + String key = page.getId(); + boolean loggedOn = requestContext.getRequest().getUserPrincipal() != null; + boolean anonymous = !loggedOn; + PageActionAccess pageActionAccess = null; + + Map sessionActions = null; + synchronized (this) + { + sessionActions = (Map) requestContext.getSessionAttribute(PAGE_ACTION_ACCESS_MAP_SESSION_ATTR_KEY); + if (sessionActions == null) + { + sessionActions = new HashMap(); + requestContext.setSessionAttribute(PAGE_ACTION_ACCESS_MAP_SESSION_ATTR_KEY, sessionActions); + } + else + { + pageActionAccess = (PageActionAccess) sessionActions.get(key); + } + } + synchronized (sessionActions) + { + if (pageActionAccess == null) + { + pageActionAccess = new PageActionAccess(anonymous, page); + sessionActions.put(key, pageActionAccess); + } + else + { + pageActionAccess.checkReset(anonymous, page); + } + } + + return pageActionAccess; + } + + public String toString() + { + return "ProfilerValve"; + } + + protected Page getRequestedPage(RequestContext request) + { + String path = request.getPath(); + if (path == null) + { + return null; + } + + PortalSiteSessionContext sessionContext = (PortalSiteSessionContext) request + .getSessionAttribute(PORTAL_SITE_SESSION_CONTEXT_ATTR_KEY); + if (path.endsWith(Page.DOCUMENT_TYPE)) + { + try + { + return sessionContext.getPageManager().getPage(path); + } + catch (PageNotFoundException e) + { + log.warn("Exception in request pipeline: " + e.getMessage(), e); + } + catch (NodeException e) + { + log.warn("Exception in request pipeline: " + e.getMessage(), e); + } + catch (Exception e) + { + log.warn("Exception in request pipeline: " + e.getMessage(), e); + } + return null; + } + + try + { + Folder folder = sessionContext.getPageManager().getFolder(path); + if (folder != null) + { + String defaultPage = folder.getDefaultPage(); + if (defaultPage != null) + { + return folder.getPage(defaultPage); + } + //TODO + } + } + catch (PageNotFoundException e) + { + log.warn("Exception in request pipeline: " + e.getMessage(), e); + } + catch (FolderNotFoundException e) + { + log.warn("Exception in request pipeline: " + e.getMessage(), e); + } + catch (InvalidFolderException e) + { + log.warn("Exception in request pipeline: " + e.getMessage(), e); + } + catch (NodeException e) + { + log.warn("Exception in request pipeline: " + e.getMessage(), e); + } + catch (Exception e) + { + + log.warn("Exception in request pipeline: " + e.getMessage(), e); + } + return null; + } +} Property changes on: pal-portal/trunk/portal/files/components/portal/src/java/org/apache/jetspeed/profiler/impl/PagePathValveImpl.java ___________________________________________________________________ Name: svn:eol-style + native Modified: pal-portal/trunk/portal/patches/src/webapp/WEB-INF/assembly/pipelines.xml =================================================================== --- pal-portal/trunk/portal/patches/src/webapp/WEB-INF/assembly/pipelines.xml 2007-06-01 08:04:46 UTC (rev 172) +++ pal-portal/trunk/portal/patches/src/webapp/WEB-INF/assembly/pipelines.xml 2007-06-07 08:47:40 UTC (rev 173) @@ -1,8 +1,72 @@ Index: src/webapp/WEB-INF/assembly/pipelines.xml =================================================================== ---- src/webapp/WEB-INF/assembly/pipelines.xml (リビジョン 539124) +--- src/webapp/WEB-INF/assembly/pipelines.xml (リビジョン 543176) +++ src/webapp/WEB-INF/assembly/pipelines.xml (作業コピー) -@@ -301,6 +301,7 @@ +@@ -106,6 +106,30 @@ + --> + <constructor-arg index="3"><value>true</value></constructor-arg> + </bean> ++ <bean id="pagePathValve" ++ class="org.apache.jetspeed.profiler.impl.PagePathValveImpl" ++ init-method="initialize" ++ > ++ <constructor-arg index="0"> ++ <ref bean="org.apache.jetspeed.profiler.Profiler" /> ++ </constructor-arg> ++ <constructor-arg index="1"> ++ <ref bean="org.apache.jetspeed.portalsite.PortalSite" /> ++ </constructor-arg> ++ <!-- ++ request fallback to root folder/page enabled by default; ++ if set to false, requests generate HTTP 403/404 errors ++ for access errors or missing pages ++ --> ++ <constructor-arg index="2"><value>true</value></constructor-arg> ++ <!-- ++ use last visited page histories to select default page ++ for folder navigational urls; if set to false, the ++ default page specified in PSML, (or the first page in ++ the folder), is always selected ++ --> ++ <constructor-arg index="3"><value>true</value></constructor-arg> ++ </bean> + + <!-- + To create a new page when a user first logs in from their roles, +@@ -305,6 +329,32 @@ + </list> + </constructor-arg> + </bean> ++ ++ <bean id="pagepath-pipeline" ++ class="org.apache.jetspeed.pipeline.JetspeedPipeline" ++ init-method="initialize" ++ > ++ <constructor-arg> ++ <value>PagePathPipeline</value> ++ </constructor-arg> ++ <constructor-arg> ++ <list> ++ <ref bean="capabilityValve"/> ++ <ref bean="portalURLValve"/> ++ <ref bean="securityValve"/> ++ <ref bean="localizationValve"/> ++ <ref bean="passwordCredentialValve"/> ++ <ref bean="loginValidationValve"/> ++ <ref bean="pagePathValve"/> ++ <ref bean="containerValve"/> ++ <ref bean="actionValve"/> ++ <ref bean="DecorationValve" /> ++ <ref bean="headerAggregatorValvePortal"/> ++ <ref bean="aggregatorValve"/> ++ <ref bean="cleanUpValve"/> ++ </list> ++ </constructor-arg> ++ </bean> + + <bean id="login-pipeline" + class="org.apache.jetspeed.pipeline.JetspeedPipeline" +@@ -317,6 +367,7 @@ <list> <ref bean="capabilityValve"/> <ref bean="localizationValve"/> @@ -10,3 +74,13 @@ <ref bean="loginViewValve"/> </list> </constructor-arg> +@@ -493,6 +544,9 @@ + <entry key='/portal'> + <value>jetspeed-pipeline</value> + </entry> ++ <entry key='/page'> ++ <value>pagepath-pipeline</value> ++ </entry> + <entry key='/ajaxapi'> + <value>ajax-pipeline</value> + </entry> Modified: pal-portal/trunk/portal/patches/src/webapp/WEB-INF/web.xml =================================================================== --- pal-portal/trunk/portal/patches/src/webapp/WEB-INF/web.xml 2007-06-01 08:04:46 UTC (rev 172) +++ pal-portal/trunk/portal/patches/src/webapp/WEB-INF/web.xml 2007-06-07 08:47:40 UTC (rev 173) @@ -1,28 +1,19 @@ Index: src/webapp/WEB-INF/web.xml =================================================================== ---- src/webapp/WEB-INF/web.xml (リビジョン 392606) +--- src/webapp/WEB-INF/web.xml (リビジョン 543176) +++ src/webapp/WEB-INF/web.xml (作業コピー) -@@ -35,23 +35,19 @@ - <filter-name>AJAXFilter</filter-name> - <filter-class>org.apache.jetspeed.ajax.AJAXFilter</filter-class> - </filter> -- <!-- - <filter> - <filter-name>PortalFilter</filter-name> - <filter-class>org.apache.jetspeed.login.filter.PortalFilter</filter-class> - </filter> -- --> - <filter-mapping> - <filter-name>AJAXFilter</filter-name> - <url-pattern>*.ajax</url-pattern> - </filter-mapping> --<!-- - - <filter-mapping> - <filter-name>PortalFilter</filter-name> - <url-pattern>/*</url-pattern> - </filter-mapping> ----> - - <listener> - <listener-class>org.apache.jetspeed.webapp.logging.Log4JConfigurator</listener-class> +@@ -153,6 +153,14 @@ + /portal/* + </url-pattern> + </servlet-mapping> ++ <servlet-mapping> ++ <servlet-name> ++ jetspeed ++ </servlet-name> ++ <url-pattern> ++ /page/* ++ </url-pattern> ++ </servlet-mapping> + <servlet-mapping> + <servlet-name> + jetspeed