You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by at...@apache.org on 2012/10/10 14:43:23 UTC

svn commit: r1396567 [2/3] - in /rave/sandbox/content-services: rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/ rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/ rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/co...

Copied: rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedHandlerMethodInterceptorAdapter.java (from r1390464, rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedHandlerInterceptorAdapter.java)
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedHandlerMethodInterceptorAdapter.java?p2=rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedHandlerMethodInterceptorAdapter.java&p1=rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedHandlerInterceptorAdapter.java&r1=1390464&r2=1396567&rev=1396567&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedHandlerInterceptorAdapter.java (original)
+++ rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedHandlerMethodInterceptorAdapter.java Wed Oct 10 12:43:21 2012
@@ -7,21 +7,26 @@ import javax.servlet.http.HttpServletReq
 import javax.servlet.http.HttpServletResponse;
 
 import org.springframework.ui.ExtendedModelMap;
+import org.springframework.web.method.HandlerMethod;
 import org.springframework.web.servlet.HandlerMapping;
 import org.springframework.web.servlet.ModelAndView;
 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
 
-public abstract class RoutedHandlerInterceptorAdapter extends HandlerInterceptorAdapter {
+public abstract class RoutedHandlerMethodInterceptorAdapter extends HandlerInterceptorAdapter {
 
+    protected HandlerMethodContext getHandlerMethodContext(HttpServletRequest request) {
+        return (HandlerMethodContext)request.getAttribute(RouteMapping.HANDLER_METHOD_CONTEXT);
+    }
     @Override
     public final boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
-        if (handler instanceof RoutedHandlerMethod && request.getAttribute(RoutedHandlerMethod.HANDLER_CONTEXT) != null) {
-            ExtendedModelMap m = (ExtendedModelMap)request.getAttribute(RoutedHandlerMethod.PREHANDLE_INTERCEPTOR_MODEL);
+        HandlerMethodContext context = getHandlerMethodContext(request);
+        if (context != null) {
+            ExtendedModelMap m = (ExtendedModelMap)request.getAttribute(RouteMapping.PREHANDLE_INTERCEPTOR_MODEL);
             if (m == null) {
                 m = new ExtendedModelMap();
-                request.setAttribute(RoutedHandlerMethod.PREHANDLE_INTERCEPTOR_MODEL, m);
+                request.setAttribute(RouteMapping.PREHANDLE_INTERCEPTOR_MODEL, m);
             }
-            return preHandle(request, response, (RoutedHandlerMethod)handler, (HandlerContext) request.getAttribute(RoutedHandlerMethod.HANDLER_CONTEXT), m);
+            return preHandle(request, response, (HandlerMethod)handler, context, m);
         }
         // else: be lenient
         return true;
@@ -29,15 +34,17 @@ public abstract class RoutedHandlerInter
 
     @Override
     public final void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
-        if (handler instanceof RoutedHandlerMethod && request.getAttribute(RoutedHandlerMethod.HANDLER_CONTEXT) != null) {
-            postHandle(request, response, (RoutedHandlerMethod)handler, (HandlerContext) request.getAttribute(RoutedHandlerMethod.HANDLER_CONTEXT), modelAndView);
+        HandlerMethodContext context = getHandlerMethodContext(request);
+        if (context != null) {
+            postHandle(request, response, (HandlerMethod)handler, context, modelAndView);
         }
     }
 
     @Override
     public final void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
-        if (handler instanceof RoutedHandlerMethod && request.getAttribute(RoutedHandlerMethod.HANDLER_CONTEXT) != null) {
-            afterCompletion(request, response, (RoutedHandlerMethod)handler, (HandlerContext) request.getAttribute(RoutedHandlerMethod.HANDLER_CONTEXT), ex);
+        HandlerMethodContext context = getHandlerMethodContext(request);
+        if (context != null) {
+            afterCompletion(request, response, (HandlerMethod)handler, context, ex);
         }
     }
 
@@ -48,13 +55,13 @@ public abstract class RoutedHandlerInter
         return (variables != null) ? variables : Collections.<String, String>emptyMap();
     }
 
-    protected boolean preHandle(HttpServletRequest request, HttpServletResponse response, RoutedHandlerMethod handler, HandlerContext context, ExtendedModelMap modelMap) throws Exception {
+    protected boolean preHandle(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler, HandlerMethodContext context, ExtendedModelMap modelMap) throws Exception {
         return true;
     }
 
-    protected void postHandle(HttpServletRequest request, HttpServletResponse response, RoutedHandlerMethod handler, HandlerContext context, ModelAndView modelAndView) throws Exception {
+    protected void postHandle(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler, HandlerMethodContext context, ModelAndView modelAndView) throws Exception {
     }
 
-    protected void afterCompletion(HttpServletRequest request, HttpServletResponse response, RoutedHandlerMethod handler, HandlerContext context, Exception ex) throws Exception {
+    protected void afterCompletion(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler, HandlerMethodContext context, Exception ex) throws Exception {
     }
 }

Copied: rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedPageInterceptorAdapter.java (from r1390464, rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/NestedHandlerInterceptorAdapter.java)
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedPageInterceptorAdapter.java?p2=rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedPageInterceptorAdapter.java&p1=rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/NestedHandlerInterceptorAdapter.java&r1=1390464&r2=1396567&rev=1396567&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/NestedHandlerInterceptorAdapter.java (original)
+++ rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedPageInterceptorAdapter.java Wed Oct 10 12:43:21 2012
@@ -4,37 +4,38 @@ import javax.servlet.http.HttpServletReq
 import javax.servlet.http.HttpServletResponse;
 
 import org.springframework.ui.ExtendedModelMap;
+import org.springframework.web.method.HandlerMethod;
 import org.springframework.web.servlet.ModelAndView;
 
-public abstract class NestedHandlerInterceptorAdapter extends RoutedHandlerInterceptorAdapter {
+public abstract class RoutedPageInterceptorAdapter extends RoutedHandlerMethodInterceptorAdapter {
 
-    protected final boolean preHandle(HttpServletRequest request, HttpServletResponse response, RoutedHandlerMethod handler, HandlerContext context, ExtendedModelMap modelMap) throws Exception {
-        if (handler instanceof NestedHandlerMethod) {
-            return preHandle(request, response, (NestedHandlerMethod)handler, (NestedHandlerContext)context, modelMap);
+    protected final boolean preHandle(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler, HandlerMethodContext context, ExtendedModelMap modelMap) throws Exception {
+        if (context.isPageFragmentContext()) {
+            return preHandle(request, response, handler, (PageFragmentContext)context, modelMap);
         }
         // else: be lenient
         return true;
     }
 
-    protected final void postHandle(HttpServletRequest request, HttpServletResponse response, RoutedHandlerMethod handler, HandlerContext context, ModelAndView modelAndView) throws Exception {
-        if (handler instanceof NestedHandlerMethod) {
-            postHandle(request, response, (NestedHandlerMethod)handler, (NestedHandlerContext)context, modelAndView);
+    protected final void postHandle(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler, HandlerMethodContext context, ModelAndView modelAndView) throws Exception {
+        if (context.isPageFragmentContext()) {
+            postHandle(request, response, handler, (PageFragmentContext)context, modelAndView);
         }
     }
 
-    protected final void afterCompletion(HttpServletRequest request, HttpServletResponse response, RoutedHandlerMethod handler, HandlerContext context, Exception ex) throws Exception {
-        if (handler instanceof NestedHandlerMethod) {
-            afterCompletion(request, response, (NestedHandlerMethod)handler, (NestedHandlerContext)context, ex);
+    protected final void afterCompletion(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler, HandlerMethodContext context, Exception ex) throws Exception {
+        if (context.isPageFragmentContext()) {
+            afterCompletion(request, response, handler, (PageFragmentContext)context, ex);
         }
     }
 
-    protected boolean preHandle(HttpServletRequest request, HttpServletResponse response, NestedHandlerMethod handler, NestedHandlerContext context, ExtendedModelMap modelMap) throws Exception {
+    protected boolean preHandle(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler, PageFragmentContext context, ExtendedModelMap modelMap) throws Exception {
         return true;
     }
 
-    protected void postHandle(HttpServletRequest request, HttpServletResponse response, NestedHandlerMethod handler, NestedHandlerContext context, ModelAndView modelAndView) throws Exception {
+    protected void postHandle(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler, PageFragmentContext context, ModelAndView modelAndView) throws Exception {
     }
 
-    protected void afterCompletion(HttpServletRequest request, HttpServletResponse response, NestedHandlerMethod handler, NestedHandlerContext context, Exception ex) throws Exception {
+    protected void afterCompletion(HttpServletRequest request, HttpServletResponse response, HandlerMethod handler, PageFragmentContext context, Exception ex) throws Exception {
     }
 }

Added: rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedPathHelper.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedPathHelper.java?rev=1396567&view=auto
==============================================================================
--- rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedPathHelper.java (added)
+++ rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedPathHelper.java Wed Oct 10 12:43:21 2012
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.rave.portal.web.mvc;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.web.util.UrlPathHelper;
+
+public class RoutedPathHelper extends UrlPathHelper {
+
+    public static class RoutedPathParts {
+        public String fullPath;
+        public String routePath;
+        public String componentPath;
+        public String handlerPath;
+    }
+
+    private boolean handlerPath;
+    private boolean alwaysUseFullPath;
+
+    public RoutedPathHelper(boolean handlerPath, boolean alwaysUseFullPath) {
+        this.handlerPath = handlerPath;
+        setAlwaysUseFullPath(alwaysUseFullPath);
+    }
+
+    public RoutedPathHelper(boolean handlerPath) {
+        this.handlerPath = handlerPath;
+    }
+
+    @Override
+    public void setAlwaysUseFullPath(final boolean alwaysUseFullPath) {
+        super.setAlwaysUseFullPath(alwaysUseFullPath);
+        this.alwaysUseFullPath = alwaysUseFullPath;
+    }
+
+    public boolean isAlwaysUseFullPath() {
+        return alwaysUseFullPath;
+    }
+
+    @Override
+    public String getLookupPathForRequest(HttpServletRequest request) {
+        RoutedPathParts paths = getRoutedPathPartsForRequest(request);
+        return handlerPath ? paths.handlerPath : paths.routePath;
+    }
+
+    public RoutedPathParts getRoutedPathParts(String lookupPath) {
+        RoutedPathParts paths = new RoutedPathParts();
+        paths.fullPath = lookupPath;
+        paths.routePath = lookupPath;
+        int idx = paths.routePath.indexOf("./");
+        if (idx != -1) {
+            paths.componentPath = paths.routePath.substring(idx+1);
+            paths.routePath = paths.routePath.substring(0, idx);
+
+            idx = paths.componentPath.indexOf("./");
+            if (idx != -1) {
+                paths.handlerPath = paths.componentPath.substring(idx+1);
+                paths.componentPath = paths.componentPath.substring(0, idx);
+            }
+        }
+        return paths;
+    }
+
+    public RoutedPathParts getRoutedPathPartsForRequest(HttpServletRequest request) {
+        return getRoutedPathParts(super.getLookupPathForRequest(request));
+    }
+}

Propchange: rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedPathHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedPathHelper.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedRequestMappingHandlerMapping.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedRequestMappingHandlerMapping.java?rev=1396567&r1=1396566&r2=1396567&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedRequestMappingHandlerMapping.java (original)
+++ rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/RoutedRequestMappingHandlerMapping.java Wed Oct 10 12:43:21 2012
@@ -16,22 +16,25 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.apache.rave.portal.web.mvc;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.StringTokenizer;
 
 import javax.servlet.http.HttpServletRequest;
 
 import org.apache.commons.lang.StringUtils;
-import org.apache.rave.portal.web.mvc.config.ConfigManager;
-import org.apache.rave.portal.web.mvc.config.Config;
+import org.apache.rave.portal.web.mvc.config.PageFragment;
+import org.apache.rave.portal.web.mvc.config.PagesConfig;
+import org.apache.rave.portal.web.mvc.config.PagesConfigManager;
 import org.apache.rave.portal.web.mvc.config.Route;
+import org.apache.rave.portal.web.mvc.utils.PathUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.core.annotation.AnnotationUtils;
@@ -45,6 +48,7 @@ import org.springframework.web.method.Ha
 import org.springframework.web.method.HandlerMethodSelector;
 import org.springframework.web.servlet.HandlerExecutionChain;
 import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.HandlerMapping;
 import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping;
 import org.springframework.web.servlet.mvc.condition.ConsumesRequestCondition;
 import org.springframework.web.servlet.mvc.condition.HeadersRequestCondition;
@@ -54,39 +58,31 @@ import org.springframework.web.servlet.m
 import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;
 import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
 import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
+import org.springframework.web.util.UrlPathHelper;
 
-/**
- * @version "$Id$"
- */
-public class RoutedRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
+public class RoutedRequestMappingHandlerMapping  extends RequestMappingHandlerMapping {
 
     private static final Logger log = LoggerFactory.getLogger(RoutedRequestMappingHandlerMapping.class);
 
-    protected static class ActionMethodInfo {
-        public boolean named;
-        public boolean defaultGetMethod;
-        public String name;
-        public Method method;
-        public RequestMappingInfo info;
-        public RequestMapping mapping;
-    }
-
-    protected boolean alwaysUseFullPath;
-
-    private ConfigManager configManager;
-
-    private volatile Config config;
-
-    private HandlerConfigMapping handlerConfigMapping = new HandlerConfigMapping();
-
     // temporary hacked open *references* to the real but private handlerMethods and urlMap maps in AbstractHandlerMethodMapping.java
     private Map<RequestMappingInfo, HandlerMethod> handlerMethods;
     private MultiValueMap<String, RequestMappingInfo> urlMap = new LinkedMultiValueMap<String, RequestMappingInfo>();
 
+    private RoutedPathHelper routedPathHelper = new RoutedPathHelper(false);
+    private RoutedPathHelper handlerPathHelper;
+
+    private PagesConfigManager configManager;
+    private volatile PagesConfig config;
+    private String mountPath;
+
     Map<String, List<HandlerInterceptor>> routeInterceptors = new HashMap<String, List<HandlerInterceptor>>();
+    Map<String, List<HandlerInterceptor>> pageInterceptors = new HashMap<String, List<HandlerInterceptor>>();
+
+    private RouteMappings routeMappings = new RouteMappings();
 
     public RoutedRequestMappingHandlerMapping() {
         super();
+
         // temporary dirty hack to access private handlerMethods and urlMap maps in AbstractHandlerMethodMapping.java
         // see #getHandlerMethodsInternal() and #getUrlMapInternal() methods which should be provided on that class
         try {
@@ -104,6 +100,9 @@ public class RoutedRequestMappingHandler
             throw new RuntimeException("Unexpected", e);
         }
         // end temporary dirty hack
+
+        // Use our own RoutedPathHelper
+        super.setUrlPathHelper(routedPathHelper);
     }
 
     /**
@@ -122,8 +121,21 @@ public class RoutedRequestMappingHandler
         return this.urlMap;
     }
 
-    protected HandlerConfigMapping getHandlerConfigMapping() {
-        return handlerConfigMapping;
+    @Override
+    protected boolean isHandler(Class<?> beanType) {
+        return (AnnotationUtils.findAnnotation(beanType, Routed.class) != null);
+    }
+
+    @Override
+    public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
+        log.error("Setting custom UrlPathHelper disabled: for now only supporting 'buildin' RoutedPathHelper");
+    }
+
+    @Override
+    protected void initHandlerMethods() {
+        handlerPathHelper = new RoutedPathHelper(true, routedPathHelper.isAlwaysUseFullPath());
+        config = configManager.getConfig();
+        processConfig();
     }
 
     public void setRouteInterceptors(Map<String, List<HandlerInterceptor>> map) {
@@ -132,106 +144,157 @@ public class RoutedRequestMappingHandler
         }
     }
 
-    @Override
-    protected boolean isHandler(Class<?> beanType) {
-        return (AnnotationUtils.findAnnotation(beanType, Routed.class) != null);
+    public void setPageInterceptors(Map<String, List<HandlerInterceptor>> map) {
+        if (map != null && !map.isEmpty()) {
+            this.pageInterceptors.putAll(map);
+        }
     }
 
-    @Override
-    protected void initHandlerMethods() {
-        config = configManager.getConfig();
-        processConfig();
+    public void setConfigManager(PagesConfigManager configManager) {
+        this.configManager = configManager;
     }
 
-    protected void reloadConfigIfNeeded() {
+    protected PagesConfigManager getConfigManager() {
+        return configManager;
+    }
 
-        Config latestConfiguration = configManager.getConfig();
-        if ((config == null && latestConfiguration != null) ||
-                (config != null && latestConfiguration == null) ||
-                (config != latestConfiguration)) {
-            synchronized (configManager) {
-               config = latestConfiguration;
-               processConfig();
+    protected PagesConfig getConfig() {
+        return config;
+    }
+
+    protected RouteMappings getRouteMappings() {
+        return routeMappings;
+    }
+
+    protected Class getRoutedController(String controllerClassName) {
+        Class controller = null;
+        try {
+            controller = ClassUtils.getUserClass(Class.forName(controllerClassName));
+        } catch (ClassNotFoundException e) {
+            if (log.isDebugEnabled()) {
+                log.error("Can not find class", e);
+            } else {
+                log.error("Can not find class for controller: {}", controllerClassName);
             }
         }
+        if (controller != null && AnnotationUtils.findAnnotation(controller, Routed.class) == null) {
+            controller = null;
+        }
+        return controller;
     }
 
-    protected ActionMethodInfo getActionMethodInfo(Method method, boolean defaultGetRequestMapping) {
-        ActionMethodInfo ami = new ActionMethodInfo();
-        ami.method = method;
+    protected RequestMappingInfo createRouteMappingInfo(String path) {
+        return createMappingInfo(true, null, new String[]{path});
+    }
+
+    protected RequestMappingInfo createMappingInfo(boolean routedMapping, RequestMapping annotation, String[] patterns) {
+        log.info("Creating mapping for patterns:[{}]", patterns);
+        final PatternsRequestCondition requestCondition = new PatternsRequestCondition(
+                patterns, routedMapping ? routedPathHelper : handlerPathHelper, getPathMatcher(), useSuffixPatternMatch(), useTrailingSlashMatch());
+        return new RequestMappingInfo(
+                requestCondition,
+                new RequestMethodsRequestCondition(annotation != null ? annotation.method() : null),
+                new ParamsRequestCondition(annotation != null ? annotation.params() : null),
+                new HeadersRequestCondition(annotation != null ? annotation.headers() : null),
+                new ConsumesRequestCondition(annotation != null ? annotation.consumes() : null, annotation != null ? annotation.headers() : null),
+                new ProducesRequestCondition(annotation != null ? annotation.produces() : null, annotation != null ? annotation.headers() : null),
+                null);
+    }
+
+    protected HandlerMethodConfig getHandlerMethodConfig(Method method, Object controllerBean) {
+        HandlerMethod handlerMethod = new HandlerMethod(controllerBean, method);
+
         RequestMapping mapping = AnnotationUtils.findAnnotation(method, RequestMapping.class);
-        ami.mapping = mapping;
         // only use (allow) first RequestMapping pattern values, if defined at all
         String paths[] = (mapping != null && mapping.value().length > 0) ?  new String[]{mapping.value()[0]} : null;
-        ami.info = createMappingInfo(mapping, paths);
+        RequestMappingInfo info = createMappingInfo(false, mapping, paths);
+
         Named named = AnnotationUtils.findAnnotation(method, Named.class);
-        ami.named = named != null;
-        if (ami.named) {
-            ami.name = named.view();
-            if ("".equals(ami.name)) {
-                ami.name = "default";
+        String name = null;
+        if (named != null) {
+            name = named.value();
+            if (StringUtils.isEmpty(name)) {
+                name = "default";
             }
         }
-        else {
-            ami.name = method.getName();
-        }
-        if (defaultGetRequestMapping) {
-            boolean defaultGetMethod = paths == null;
-            if (paths != null && paths[0] != null) {
-                if ("".equals(paths[0]) || "/".equals(paths[0])) {
-                    defaultGetMethod = true;
-                }
-            }
-            if (defaultGetMethod && !ami.info.getMethodsCondition().getMethods().isEmpty()) {
-                defaultGetMethod = !ami.info.getMethodsCondition().getMethods().contains(RequestMethod.GET);
-            }
-            // TODO: ensure no other conditions enabled
-            ami.defaultGetMethod = defaultGetMethod;
+
+        boolean defaultMethod =
+                ((paths == null) ||
+                        (paths.length > 0 &&
+                                paths[0] != null &&
+                                ("".equals(paths[0]) || "/".equals(paths[0]))
+                        )
+                );
+
+        if (defaultMethod && !info.getMethodsCondition().getMethods().isEmpty()) {
+            defaultMethod = !info.getMethodsCondition().getMethods().contains(RequestMethod.GET);
         }
-        return ami;
+        // TODO: ensure no other conditions enabled
+
+        HandlerMethodConfig config = new HandlerMethodConfig(handlerMethod, info, name, defaultMethod);
+
+        return config;
     }
 
-    protected Map<String, ActionMethodInfo> getActionMethodInfos(Class<?> userType, boolean defaultGetRequestMapping) {
-        Map<String, ActionMethodInfo> map = new HashMap<String, ActionMethodInfo>();
-        if (!isHandler(userType)) {
-            return map;
-        }
-        Set<Method> methods = HandlerMethodSelector.selectMethods(userType, new ReflectionUtils.MethodFilter() {
+    protected Map<String, HandlerMethodConfig> getHandlerMethodConfigs(Class controller) {
+        Map<String, HandlerMethodConfig> map = new HashMap<String, HandlerMethodConfig>();
+
+        Set<Method> methods = HandlerMethodSelector.selectMethods(controller, new ReflectionUtils.MethodFilter() {
             public boolean matches(Method method) {
                 return AnnotationUtils.findAnnotation(method, Named.class) != null ||
                         AnnotationUtils.findAnnotation(method, RequestMapping.class) != null;
             }
         });
+
         if (!methods.isEmpty()) {
-            ActionMethodInfo amiDefault = null;
-            ActionMethodInfo ami;
+            Object controllerBean = getApplicationContext().getBean(controller);
+            HandlerMethodConfig hmc;
             for (Method m : methods) {
-                ami = getActionMethodInfo(m, defaultGetRequestMapping);
-                if (defaultGetRequestMapping ) {
-                    if (ami.defaultGetMethod) {
-                        if (amiDefault == null || "default".equals(ami.name)) {
-                            amiDefault = ami;
-                        }
-                    }
+                hmc = getHandlerMethodConfig(m, controllerBean);
+                hmc = map.put(hmc.getName(), hmc);
+                if (hmc != null) {
+                    log.error("Multiple RequestMapping or Named methods in " + controller.getName() + " named \"" + hmc.getName() + "\", overriding ...");
                 }
-                ami = map.put(ami.name, ami);
-                if (ami != null) {
-                    log.error("Multiple RequestMapping or Named methods in " + userType.getName() + " named \"" + ami.name + "\", overriding ...");
-                }
-            }
-            if (amiDefault != null) {
-                map.put("default", amiDefault);
             }
         }
         return map;
     }
 
-    protected void processConfig() {
+    protected boolean ensureHasDefaultHandler(Map<String, HandlerMethodConfig> handlers) {
+        HandlerMethodConfig defaultHmc = null;
+        for (HandlerMethodConfig hmc: handlers.values()) {
+            if ("default".equals(hmc.getName()) || (defaultHmc == null && hmc.isDefaultMethod())) {
+                defaultHmc = hmc;
+            }
+        }
+        if (defaultHmc != null) {
+            if (!"default".equals(defaultHmc.getName())) {
+                // special case: no named default method found so adding one for it
+                handlers.put("default", defaultHmc);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    protected void reloadConfigIfNeeded() {
+
+        PagesConfig latestConfiguration = configManager.getConfig();
+        if ((config == null && latestConfiguration != null) ||
+                (config != null && latestConfiguration == null) ||
+                (config != latestConfiguration)) {
+            synchronized (configManager) {
+                config = latestConfiguration;
+                processConfig();
+            }
+        }
+    }
 
+    protected void processConfig() {
         // reset
         getHandlerMethodsInternal().clear();
         getUrlMapInternal().clear();
-        getHandlerConfigMapping().clear();
+        getRouteMappings().clear();
 
         if (config != null) {
             for (Route route : config.getRoutes()) {
@@ -240,127 +303,205 @@ public class RoutedRequestMappingHandler
         }
     }
 
-    protected String getFirstRequestMappingInfoPattern(RequestMappingInfo info) {
-        Set<String> patterns = info.getPatternsCondition().getPatterns();
-        // Note: the patterns can only be empty or of size 1
-        return patterns.isEmpty() ? "" : patterns.iterator().next();
+    protected void processRoute(Route route) {
+        if (!StringUtils.isEmpty(route.getComponent())) {
+            if (!route.getComponent().startsWith("/")) {
+                processHandlerMethodRoute(route);
+            }
+            else {
+                processPageRoute(route);
+            }
+        }
     }
 
-    protected void processRoute(Route route) {
-        final String controller = route.getComponent();
-        if (!StringUtils.isEmpty(controller)) {
-            Class<?> controllerClass = getControllerClass(controller);
-            if (controllerClass != null) {
-                Map<String, ActionMethodInfo> infos = getActionMethodInfos(controllerClass, false);
-                if (route.getHandler() != null) {
-                    ActionMethodInfo ami = infos.get(route.getHandler());
-                    if (ami != null) {
-                        try {
-                            Object handler = getApplicationContext().getBean(controllerClass);
-                            HandlerConfigImpl config = new HandlerConfigImpl();
-                            config.setName(controller);
-                            config.setName(ami.name);
-                            config.setRoute(route);
-                            config.setMethod(new RoutedHandlerMethod(handler, ami.method, config));
-                            // ignore/force method mapping info without own path pattern: only route path will be used
-                            config.setPath("");
-                            ami.info = createMappingInfo(ami.mapping, route.getPath());
-                            registerHandlerMethod(handler, ami.method, ami.info);
-                            getHandlerConfigMapping().addHandlerConfig(config);
-                            // replace default HandlerMethod with our own nestedHandlerMethod
-                            getHandlerMethodsInternal().put(ami.info, config.getMethod());
-                        } catch (Exception e) {
-                            log.error("Error", e);
-                        }
+    protected void processHandlerMethodRoute(Route route) {
+        String controllerClassName = route.getComponent();
+        if (!StringUtils.isEmpty(controllerClassName)) {
+            Map<String, HandlerMethodConfig> handlers = routeMappings.getHandlers(controllerClassName);
+            if (handlers == null) {
+                Class controllerClass = getRoutedController(controllerClassName);
+                if (controllerClass != null) {
+                    handlers = getHandlerMethodConfigs(controllerClass);
+                    routeMappings.addHandlers(controllerClassName, handlers);
+                    if (handlers.isEmpty()) {
+                        log.warn("Ignoring Route which component has no handler methods. Route path: "+route.getPath());
                     }
                 }
                 else {
-                    RequestMappingInfo routeInfo = createMappingInfo(null, route.getPath());
-                    for (ActionMethodInfo ami : infos.values()) {
-                        try {
-                            Object handler = getApplicationContext().getBean(controllerClass);
-                            HandlerConfigImpl config = new HandlerConfigImpl();
-                            config.setName(controller);
-                            config.setName(ami.name);
-                            config.setRoute(route);
-                            config.setMethod(new RoutedHandlerMethod(handler, ami.method, config));
-                            config.setPath(getFirstRequestMappingInfoPattern(ami.info));
-                            // combine the RequestMappingInfo with the route based RequestMappingInfo (path)
-                            ami.info = routeInfo.combine(ami.info);
-                            registerHandlerMethod(handler, ami.method, ami.info);
-                            getHandlerConfigMapping().addHandlerConfig(config);
-                            // replace default HandlerMethod with our own nestedHandlerMethod
-                            getHandlerMethodsInternal().put(ami.info, config.getMethod());
-                        } catch (Exception e) {
-                            log.error("Error", e);
+                    log.error("Ignoring Route with unknown component: "+controllerClassName+". Route path: "+route.getPath());
+                }
+            }
+            if (!handlers.isEmpty()) {
+                String routeReferenceId = route.getReferenceId() != null ? route.getReferenceId() : "";
+                String routesKey = null;
+                if (!StringUtils.isEmpty(route.getHandler())) {
+                    HandlerMethodConfig hmc = handlers.get(route.getHandler());
+                    if (hmc != null) {
+                        RequestMappingInfo info = createRouteMappingInfo(route.getPath()).combine(hmc.getRequestMappingInfo());
+                        registerHandlerMethod(hmc.getHandlerMethod().getBean(), hmc.getHandlerMethod().getMethod(), info);
+                        routeMappings.getRouteMappings().put(info, new RouteHandlerMethodMapping(route, hmc));
+
+                        if (!StringUtils.isEmpty(routeReferenceId)) {
+                            if (routeMappings.getRoutes().put(routeReferenceId, route) != null) {
+                                log.warn("Warning: Route referenceId: "+routeReferenceId+" defined multiple times. Now registered for Route path: "+route.getPath());
+                            }
                         }
+                        routesKey = PathUtils.mergePaths(controllerClassName, route.getHandler());
+                    }
+                    else {
+                        log.error("Ignoring Route with unknown component handler: "+route.getHandler()+". Route path: "+route.getPath());
                     }
                 }
+                else {
+                    routesKey = controllerClassName;
+                    RequestMappingInfo routeMappingInfo = createRouteMappingInfo(route.getPath());
+                    for (HandlerMethodConfig hmc : handlers.values()) {
+                        RequestMappingInfo info = routeMappingInfo.combine(hmc.getRequestMappingInfo());
+                        registerHandlerMethod(hmc.getHandlerMethod().getBean(), hmc.getHandlerMethod().getMethod(), info);
+                        routeMappings.getRouteMappings().put(info, new RouteHandlerMethodMapping(route, hmc));
+                    }
+                }
+                if (routesKey != null) {
+                    Map<String, Route> routesMap = routeMappings.getRoutesMap().get(routesKey);
+                    if (routesMap == null) {
+                        routesMap = new HashMap<String, Route>();
+                        routeMappings.getRoutesMap().put(routesKey, routesMap);
+                    }
+                    routesMap.put(routeReferenceId, route);
+                }
             }
         }
+        else {
+            log.warn("Ignoring Route with unspecified component. Route path: "+route.getPath());
+        }
     }
 
-    //*************************************************************************************
-    // UTILITIES
-    //*************************************************************************************
-    protected Class<?> getControllerClass(String controller) {
-        if (controller == null) {
-            // TODO: temporarily direct injection of ViewOnlyController, should become pluggable/configurable
-            controller = ViewOnlyController.class.getName();
-        }
-        Class<?> userType = classFromString(controller);
-        return userType != null ? ClassUtils.getUserClass(userType) : null;
+    protected void processPageRoute(Route route) {
+        String pagePath = route.getComponent();
+        String pageName = pagePath.substring(1);
+
+        PageFragmentConfig pfc = routeMappings.getPages().get(pageName);
+        if (pfc == null) {
+            PageFragment pf = config.getPages().get(pageName);
+            if (pf != null) {
+                pfc = buildPageFragmentConfig(pf, null, route);
+                if (pfc != null) {
+                    routeMappings.getPages().put(pageName, pfc);
+                }
+            }
+        }
+        if (pfc != null) {
+            HandlerMethodConfig hmc = pfc.getHandlerMethodConfig();
+            RequestMappingInfo info = createRouteMappingInfo(route.getPath());
+            registerHandlerMethod(hmc.getHandlerMethod().getBean(), hmc.getHandlerMethod().getMethod(), info);
+            routeMappings.getRouteMappings().put(info, new RoutePageMapping(route, pfc));
+
+            Map<String, Route> routesMap = routeMappings.getRoutesMap().get(pagePath);
+            if (routesMap == null) {
+                routesMap = new HashMap<String, Route>();
+                routeMappings.getRoutesMap().put(pagePath, routesMap);
+            }
+            String routeReferenceId = route.getReferenceId() != null ? route.getReferenceId() : "";
+            routesMap.put(routeReferenceId, route);
+
+            if (!StringUtils.isEmpty(routeReferenceId)) {
+                if (routeMappings.getRoutes().put(routeReferenceId, route) != null) {
+                    log.warn("Warning: Route referenceId: "+routeReferenceId+" defined multiple times. Now registered for Route path: "+route.getPath());
+                }
+            }
+        }
     }
 
-    private Class<?> classFromString(String controller) {
-        if (controller == null) {
-            log.warn("Provided controller class was null");
+    protected PageFragmentConfig buildPageFragmentConfig(PageFragment pf, PageFragmentConfig parent, Route route) {
+        String controllerClassName = pf.getController();
+        if (StringUtils.isEmpty(controllerClassName)) {
+            // TODO: make this configurable/pluggable
+            controllerClassName = ViewOnlyController.class.getName();
+        }
+        Map<String, HandlerMethodConfig> handlers = routeMappings.getHandlers(controllerClassName);
+        if (handlers == null) {
+            Class controllerClass = getRoutedController(controllerClassName);
+            if (controllerClass != null) {
+                handlers = getHandlerMethodConfigs(controllerClass);
+                routeMappings.addHandlers(controllerClassName, handlers);
+            }
+            else {
+                log.error("Ignoring Route which page fragment has an unknown controller: " + controllerClassName + ". Route path: " + route.getPath());
+                // no need to try again
+                routeMappings.addHandlers(controllerClassName, Collections.EMPTY_MAP);
+                return null;
+            }
+        }
+        if (handlers.isEmpty()) {
+            log.warn("Ignoring Route which page fragment controller: "+controllerClassName+" has no handler methods. Route path: "+route.getPath());
             return null;
         }
-        try {
+        if (!ensureHasDefaultHandler(handlers)) {
+            log.error("Ignoring Route which page fragment controller: " + controllerClassName + " has no default handler method. Route path: " + route.getPath());
+        }
 
-            return Class.forName(controller);
-        } catch (ClassNotFoundException e) {
-            if (log.isDebugEnabled()) {
-                log.error("Could not find class", e);
-            } else {
-                log.error("Could not find class for controller: {}", controller);
+        ControllerHandlerMapping chm = routeMappings.getControllerMappings().get(controllerClassName);
+        if (chm == null) {
+            chm = new ControllerHandlerMapping(this, handlerPathHelper);
+            for (Map.Entry<String, HandlerMethodConfig> entry : handlers.entrySet()) {
+                if (!entry.getKey().equals("default") || entry.getValue().getName().equals("default")) {
+                    HandlerMethodConfig hmc = entry.getValue();
+                    chm.registerNamedHandlerMethod(hmc.getHandlerMethod().getBean(), hmc.getHandlerMethod().getMethod(), hmc.getRequestMappingInfo(), entry.getKey());
+                }
             }
+            routeMappings.getControllerMappings().put(controllerClassName, chm);
         }
-        return null;
-    }
 
-    protected RequestMappingInfo createMappingInfo(RequestMapping annotation, String path) {
-        return createMappingInfo(annotation, new String[]{path});
-    }
+        PageFragmentConfig pfc = new PageFragmentConfig(pf.getName(), parent, handlers.get("default"));
+        pfc.setViewName(pf.getViewName());
+        pfc.setInterceptors(pf.getInterceptors());
+        pfc.getProperties().putAll(pf.getProperties());
 
-    protected RequestMappingInfo createMappingInfo(RequestMapping annotation, String[] patterns) {
-        log.info("Creating mapping for patterns:[{}]", patterns);
-        final PatternsRequestCondition requestCondition = new PatternsRequestCondition(
-                patterns, getUrlPathHelper(), getPathMatcher(), useSuffixPatternMatch(), useTrailingSlashMatch());
-        return new RequestMappingInfo(
-                requestCondition,
-                new RequestMethodsRequestCondition(annotation != null ? annotation.method() : null),
-                new ParamsRequestCondition(annotation != null ? annotation.params() : null),
-                new HeadersRequestCondition(annotation != null ? annotation.headers() : null),
-                new ConsumesRequestCondition(annotation != null ? annotation.consumes() : null, annotation != null ? annotation.headers() : null),
-                new ProducesRequestCondition(annotation != null ? annotation.produces() : null, annotation != null ? annotation.headers() : null),
-                null);
+        for (PageFragment child : pf.getChildren()) {
+            if ( buildPageFragmentConfig(child,  pfc, route) == null) {
+                // invalid child fragment
+                return null;
+            }
+        }
+
+        return pfc;
     }
 
     @Override
     protected void handleMatch(RequestMappingInfo info, String lookupPath, HttpServletRequest request) {
         super.handleMatch(info, lookupPath, request);
-        request.setAttribute(NestedHandlerMethod.REQUEST_MAPPING_INFO, info);
-    }
+        request.setAttribute(RouteMapping.REQUEST_MAPPING_INFO, info);
 
-    protected HandlerContext createHandlerContext(HttpServletRequest request, RoutedHandlerMethod hm) {
-        return new HandlerContextImpl(getUrlPathHelper(), alwaysUseFullPath, getHandlerConfigMapping(), hm.getConfiguration(), request);
     }
 
-    public void setAlwaysUseFullPath(boolean alwaysUseFullPath) {
-        this.alwaysUseFullPath = alwaysUseFullPath;
-        super.setAlwaysUseFullPath(alwaysUseFullPath);
+    @Override
+    protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
+        HandlerExecutionChain chain = super.getHandlerExecutionChain(handler, request);
+
+        HandlerMethodContextImpl context = (HandlerMethodContextImpl)request.getAttribute(RouteMapping.HANDLER_METHOD_CONTEXT);
+        if (context != null) {
+            if (context instanceof PageFragmentContextImpl) {
+                PageFragmentConfig pfc = ((PageFragmentContextImpl)context).getPageFragmentConfig();
+                // If a child fragment config without interceptors of its own, fallback to the possible root fragment config interceptors
+                if (StringUtils.isEmpty(pfc.getInterceptors()) && pfc.getParent() != null) {
+                    pfc = pfc.getRoot();
+                }
+                List<HandlerInterceptor> interceptors = pageInterceptors.get(pfc.getInterceptors());
+                if (interceptors != null) {
+                    for (HandlerInterceptor interceptor : interceptors) {
+                        chain.addInterceptor(interceptor);
+                    }
+                }
+            }
+            Route route = context.getRoute();
+            List<HandlerInterceptor> interceptors = routeInterceptors.get(route.getInterceptors());
+            if (interceptors != null) {
+                for (HandlerInterceptor interceptor : interceptors) {
+                    chain.addInterceptor(interceptor);
+                }
+            }
+        }
+        return chain;
     }
 
     @Override
@@ -368,57 +509,93 @@ public class RoutedRequestMappingHandler
 
         reloadConfigIfNeeded();
 
-        String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
-        if (logger.isDebugEnabled()) {
-            logger.debug("Looking up handler method for path " + lookupPath);
+        if (mountPath == null) {
+            mountPath = routedPathHelper.isAlwaysUseFullPath() ? "" : routedPathHelper.getServletPath(request);
         }
 
-        HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
+        HandlerMethod handlerMethod = super.getHandlerInternal(request);
 
-        if (logger.isDebugEnabled()) {
-            if (handlerMethod != null) {
-                logger.debug("Returning handler method [" + handlerMethod + ']');
-            } else {
-                logger.debug("Did not find handler method for [" + lookupPath + ']');
-            }
-        }
-        handlerMethod = (handlerMethod != null) ? handlerMethod.createWithResolvedBean() : null;
-        if (handlerMethod != null && handlerMethod instanceof RoutedHandlerMethod) {
-            request.setAttribute(RoutedHandlerMethod.HANDLER_CONTEXT, createHandlerContext(request, (RoutedHandlerMethod)handlerMethod));
-        }
-        return handlerMethod;
-    }
+        if (handlerMethod != null) {
+            RequestMappingInfo info = (RequestMappingInfo)request.getAttribute(RouteMapping.REQUEST_MAPPING_INFO);
 
-    public void setConfigManager(ConfigManager configManager) {
-        this.configManager = configManager;
-    }
+            if (info != null) {
+                request.removeAttribute(RouteMapping.REQUEST_MAPPING_INFO);
 
-    protected ConfigManager getConfigManager() {
-        return configManager;
-    }
+                RouteMapping mapping = routeMappings.getRouteMappings().get(info);
 
-    protected Config getConfig() {
-        return config;
-    }
+                if (mapping != null) {
+                    HandlerMethodContext context = null;
+                    if (mapping instanceof RouteHandlerMethodMapping) {
+                        context = new HandlerMethodContextImpl(request, routeMappings, mapping.getRoute(), ((RouteHandlerMethodMapping)mapping).getTarget(), mountPath);
+                    }
+                    else if (mapping instanceof RoutePageMapping) {
+                        PageFragmentConfig pfc = ((RoutePageMapping)mapping).getTarget();
+                        RoutedPathHelper.RoutedPathParts paths = routedPathHelper.getRoutedPathPartsForRequest(request);
+                        if (paths.componentPath != null) {
+                            StringTokenizer st = new StringTokenizer(paths.componentPath, "/");
+                            while (st.hasMoreTokens() && pfc != null) {
+                                pfc = pfc.getChildren().get(st.nextToken());
+                            }
+                            if (pfc == null) {
+                                // TODO some 404 handling here?
+                                return null;
+                            }
+                        }
+                        HandlerMethodConfig hmc = pfc.getHandlerMethodConfig();
+                        boolean pageFragmentHandlerRequest = false;
+                        if (paths.handlerPath == null) {
+                            // check if request method is supported by "default" handler
+                            if (pfc.getHandlerMethodConfig().getRequestMappingInfo().getMethodsCondition().getMatchingCondition(request) == null) {
+                                // current request method not support
+                                // TODO: some 404 handling here?
+                                return null;
+                            }
+                        }
+                        else {
+                            String controllerClassName = pfc.getHandlerMethodConfig().getHandlerMethod().getBeanType().getName();
+                            ControllerHandlerMapping chm = routeMappings.getControllerMappings().get(controllerClassName);
+
+                            // saveguard initial pathVariables
+                            Map<String, String> pathVariables = (Map<String, String>)request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
+
+                            String handlerName = chm.lookupNamedHandlerMethod(paths.handlerPath, request);
+                            if (handlerName == null) {
+                                // TODO some 404 handling here?
+                                return null;
+                            }
+                            else {
+                                // switch to target handler
+                                hmc = routeMappings.getHandlers(controllerClassName).get(handlerName);
+                            }
+
+                            if (pathVariables != null && !pathVariables.isEmpty()) {
+                                //restore initial uriTemplateVariables and possible merge with fragment controller handler path variables
+                                Map<String, String> handlerPathVariables = (Map<String, String>)request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
+                                if (handlerPathVariables != null) {
+                                    pathVariables.putAll(handlerPathVariables);
+                                }
+                                request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, pathVariables);
+                            }
+                            // adjust and fix HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE request attribute
+                            request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, paths.fullPath);
+                            // for now remove and don't support HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE request attribute
+                            request.removeAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
 
-    protected void addHandlerContextInterceptors(HandlerExecutionChain chain, HandlerContext handlerContext, HttpServletRequest request) {
-        Route route = handlerContext.getConfig().getRoute();
-        if (route.getInterceptors() != null) {
-            List<HandlerInterceptor> interceptors = routeInterceptors.get(route.getInterceptors());
-            if (interceptors != null) {
-                for (HandlerInterceptor interceptor : interceptors) {
-                    chain.addInterceptor(interceptor);
+                            // mark this as a direct page fragment handler request: no child fragment processing will be done
+                            pageFragmentHandlerRequest = true;
+                        }
+                        handlerMethod = hmc.getHandlerMethod();
+                        context = new PageFragmentContextImpl(request, routeMappings, mapping.getRoute(), pfc, hmc, mountPath);
+
+                        if (!pageFragmentHandlerRequest) {
+                            request.setAttribute(RouteMapping.PAGE_FRAGMENT_RENDER_REQUEST, Boolean.TRUE);
+                        }
+                    }
+                    request.setAttribute(RouteMapping.HANDLER_METHOD_CONTEXT, context);
                 }
             }
         }
-    }
 
-    protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
-        HandlerExecutionChain chain = super.getHandlerExecutionChain(handler, request);
-        HandlerContext handlerContext = (HandlerContext)request.getAttribute(RoutedHandlerMethod.HANDLER_CONTEXT);
-        if (handlerContext != null) {
-            addHandlerContextInterceptors(chain, handlerContext, request);
-        }
-        return chain;
+        return handlerMethod;
     }
 }
\ No newline at end of file

Modified: rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/ViewOnlyController.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/ViewOnlyController.java?rev=1396567&r1=1396566&r2=1396567&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/ViewOnlyController.java (original)
+++ rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/ViewOnlyController.java Wed Oct 10 12:43:21 2012
@@ -25,7 +25,7 @@ public class ViewOnlyController {
 
     @Named
     @RequestMapping
-    public String render(NestedHandlerContext hc) {
-        return hc.getConfig().getViewName();
+    public String render(PageFragmentContext context) {
+        return context.getFragmentViewName();
     }
 }

Modified: rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/PageFragment.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/PageFragment.java?rev=1396567&r1=1396566&r2=1396567&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/PageFragment.java (original)
+++ rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/PageFragment.java Wed Oct 10 12:43:21 2012
@@ -70,13 +70,6 @@ public interface PageFragment {
     String getInterceptors();
 
     /**
-     *
-     * @param name name of the property to retrieve the value for
-     * @return the value of a property defined for this PageFragment, null if undefined
-     */
-    String getProperty(String name);
-
-    /**
      * @return An immutable map of properties defined for this Route, never null
      */
     Map<String, String> getProperties();

Modified: rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/Route.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/Route.java?rev=1396567&r1=1396566&r2=1396567&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/Route.java (original)
+++ rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/Route.java Wed Oct 10 12:43:21 2012
@@ -27,7 +27,7 @@ import java.util.Map;
  */
 public interface Route {
 
-    List<Route> getChildren();
+    String getReferenceId();
 
     String getPath();
 
@@ -38,13 +38,6 @@ public interface Route {
     String getInterceptors();
 
     /**
-     *
-     * @param name name of the property to retrieve the value for
-     * @return the value of a property defined for this Route, null if undefined
-     */
-    String getProperty(String name);
-
-    /**
      * @return An immutable map of properties defined for this Route, never null
      */
     Map<String, String> getProperties();

Modified: rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/enhancers/ExtendsEnhancer.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/enhancers/ExtendsEnhancer.java?rev=1396567&r1=1396566&r2=1396567&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/enhancers/ExtendsEnhancer.java (original)
+++ rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/enhancers/ExtendsEnhancer.java Wed Oct 10 12:43:21 2012
@@ -314,11 +314,6 @@ public class ExtendsEnhancer implements 
         }
 
         @Override
-        public String getProperty(String name) {
-            return properties.get(name);
-        }
-
-        @Override
         public Map<String,String> getProperties() {
             return Collections.unmodifiableMap(properties);
         }

Modified: rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/xml/XmlPageFragment.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/xml/XmlPageFragment.java?rev=1396567&r1=1396566&r2=1396567&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/xml/XmlPageFragment.java (original)
+++ rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/xml/XmlPageFragment.java Wed Oct 10 12:43:21 2012
@@ -169,15 +169,10 @@ public class XmlPageFragment implements 
     }
 
     @Override
-    public String getProperty(String name) {
-        return getProperties().get(name);
-    }
-
-    @Override
     public String toString() {
         final StringBuilder sb = new StringBuilder();
-        sb.append(this.getClass().getName());
-        sb.append(", xmlExtends=").append(xmlExtends);
+        sb.append("XmlPageFragment");
+        sb.append("{ extends='").append(xmlExtends).append('\'');
         sb.append(", name='").append(name).append('\'');
         sb.append(", controller='").append(controller).append('\'');
         sb.append('}');

Modified: rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/xml/XmlRoute.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/xml/XmlRoute.java?rev=1396567&r1=1396566&r2=1396567&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/xml/XmlRoute.java (original)
+++ rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/config/xml/XmlRoute.java Wed Oct 10 12:43:21 2012
@@ -34,11 +34,11 @@ import org.apache.rave.portal.web.mvc.co
  */
 public class XmlRoute implements Route {
 
+    private String referenceId;
     private String path;
     private String component;
     private String handler;
     private String interceptors;
-    private List<Route> children;
     private List<XmlProperty> xmlProperties;
     private Map<String,String> properties;
 
@@ -47,6 +47,16 @@ public class XmlRoute implements Route {
 
     @XmlAttribute
     @Override
+    public String getReferenceId() {
+        return referenceId;
+    }
+
+    public void setReferenceId(String referenceId) {
+        this.referenceId = referenceId;
+    }
+
+    @XmlAttribute
+    @Override
     public String getPath() {
         return path;
     }
@@ -86,16 +96,6 @@ public class XmlRoute implements Route {
         this.interceptors = interceptors;
     }
 
-    @XmlElement(name = "route", type = XmlRoute.class)
-    @Override
-    public List<Route> getChildren() {
-        return children;
-    }
-
-    public void setChildren(List<Route> children) {
-        this.children = children;
-    }
-
     @XmlElement(name = "property", type = XmlProperty.class)
     public List<XmlProperty> getXmlProperties() {
         return xmlProperties;
@@ -125,18 +125,14 @@ public class XmlRoute implements Route {
     }
 
     @Override
-    public String getProperty(String name) {
-        return getProperties().get(name);
-    }
-
-    @Override
     public String toString() {
         final StringBuilder sb = new StringBuilder();
         sb.append("XmlRoute");
-        sb.append("{path='").append(path).append('\'');
-        sb.append("{component='").append(component).append('\'');
-        sb.append("{handler ='").append(handler).append('\'');
-        sb.append("{interceptors ='").append(interceptors).append('\'');
+        sb.append("{ referenceId='").append(referenceId).append('\'');
+        sb.append(", path='").append(path).append('\'');
+        sb.append(", component='").append(component).append('\'');
+        sb.append(", handler ='").append(handler).append('\'');
+        sb.append(", interceptors ='").append(interceptors).append('\'');
         sb.append('}');
         return sb.toString();
     }

Copied: rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/servlet/PageFragmentDispatcherServlet.java (from r1391329, rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/servlet/NestedDispatcherServlet.java)
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/servlet/PageFragmentDispatcherServlet.java?p2=rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/servlet/PageFragmentDispatcherServlet.java&p1=rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/servlet/NestedDispatcherServlet.java&r1=1391329&r2=1396567&rev=1396567&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/servlet/NestedDispatcherServlet.java (original)
+++ rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/servlet/PageFragmentDispatcherServlet.java Wed Oct 10 12:43:21 2012
@@ -23,40 +23,31 @@ import java.util.Map;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.rave.portal.web.mvc.NestedHandlerContextImpl;
-import org.apache.rave.portal.web.mvc.NestedHandlerMethod;
-import org.apache.rave.portal.web.mvc.RoutedHandlerMethod;
-import org.apache.rave.portal.web.mvc.support.NestedServletRequest;
-import org.apache.rave.portal.web.mvc.support.NestedServletResponse;
+import org.apache.rave.portal.web.mvc.HandlerMethodContext;
+import org.apache.rave.portal.web.mvc.PageFragmentConfig;
+import org.apache.rave.portal.web.mvc.PageFragmentContextImpl;
+import org.apache.rave.portal.web.mvc.RouteMapping;
+import org.apache.rave.portal.web.mvc.support.PageFragmentRequest;
+import org.apache.rave.portal.web.mvc.support.PageFragmentResponse;
 import org.apache.rave.portal.web.mvc.support.ResponseHolder;
 import org.springframework.web.servlet.DispatcherServlet;
 import org.springframework.web.servlet.ModelAndView;
 import org.springframework.web.servlet.View;
 import org.springframework.web.servlet.view.InternalResourceView;
 
-public class NestedDispatcherServlet extends DispatcherServlet {
-
+public class PageFragmentDispatcherServlet extends DispatcherServlet {
 
     private static final long serialVersionUID = 1L;
 
-    protected boolean isNestedHandlerMethodRendering(HttpServletRequest request) {
-        return request.getAttribute(NestedHandlerMethod.class.getName()) != null;
-    }
-
     @Override
     protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
-        if (isNestedHandlerMethodRendering(request)) {
-            NestedServletRequest nestedRequest = new NestedServletRequest(request);
-            NestedServletResponse nestedResponse = new NestedServletResponse(response);
-
-            renderChildren(mv, nestedRequest, nestedResponse);
-
-            NestedHandlerMethod hm = (NestedHandlerMethod)mv.getModelMap().get(RoutedHandlerMethod.HANDLER_METHOD);
-            NestedHandlerContextImpl hc = (NestedHandlerContextImpl)request.getAttribute(RoutedHandlerMethod.HANDLER_CONTEXT);
-            hc.setConfig(hm.getConfiguration());
-
-            render(mv, nestedRequest, nestedResponse);
-            ResponseHolder responseHolder = nestedResponse.getResponseHolder();
+        if (isPageFragmentRendering(request)) {
+            PageFragmentRequest fragmentRequest = new PageFragmentRequest(request);
+            PageFragmentResponse fragmentResponse = new PageFragmentResponse(response);
+
+            renderChildren(mv, fragmentRequest, fragmentResponse);
+            render(mv, fragmentRequest, fragmentResponse);
+            ResponseHolder responseHolder = fragmentResponse.getResponseHolder();
             responseHolder.flush();
             if (responseHolder.getRedirectLocation() != null) {
                 response.sendRedirect(responseHolder.getRedirectLocation());
@@ -67,37 +58,48 @@ public class NestedDispatcherServlet ext
         }
     }
 
-    protected void renderChildren(ModelAndView mv, NestedServletRequest nestedRequest, NestedServletResponse hvmcResponse) throws Exception {
+    @Override
+    protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,
+                                   HttpServletRequest request) throws Exception {
+        View view = super.resolveViewName(viewName, model, locale, request);
+        if (isPageFragmentRendering(request)) {
+            setInternalResourceViewIncludeAlways(view);
+        }
+        return view;
+    }
+
+    protected boolean isPageFragmentRendering(HttpServletRequest request) {
+        HandlerMethodContext context = (HandlerMethodContext)request.getAttribute(RouteMapping.HANDLER_METHOD_CONTEXT);
+        return (context != null && context.isPageFragmentContext() && context.isPageFragmentRenderRequest());
+    }
+
+    protected void renderChildren(ModelAndView mv, PageFragmentRequest fragmentRequest, PageFragmentResponse fragmentResponse) throws Exception {
         @SuppressWarnings("unchecked")
-        Map<String, ModelAndView> ccmvMap = (Map<String, ModelAndView>) mv.getModelMap().get(NestedHandlerMethod.MODEL_AND_VIEW);
+        Map<String, ModelAndView> ccmvMap = (Map<String, ModelAndView>) mv.getModelMap().get(RouteMapping.MODEL_AND_VIEW);
         if (ccmvMap != null) {
             Map<String, ResponseHolder> ccvrMap = new LinkedHashMap<String, ResponseHolder>();
-            mv.getModelMap().addAttribute(NestedHandlerMethod.VIEW_RESPONSE_STATE, ccvrMap);
+            mv.getModelMap().addAttribute(RouteMapping.VIEW_RESPONSE_STATE, ccvrMap);
             for (Map.Entry<String, ModelAndView> entry : ccmvMap.entrySet()) {
-                NestedServletResponse childNestedResponse = new NestedServletResponse(hvmcResponse);
-                renderChildren(entry.getValue(), nestedRequest, childNestedResponse);
-                render(entry.getValue(), nestedRequest, childNestedResponse);
-                ccvrMap.put(entry.getKey(), childNestedResponse.getResponseHolder());
+                PageFragmentResponse childFragmentResponse = new PageFragmentResponse(fragmentResponse);
+                renderChildren(entry.getValue(), fragmentRequest, childFragmentResponse);
+                render(entry.getValue(), fragmentRequest, childFragmentResponse);
+                ccvrMap.put(entry.getKey(), childFragmentResponse.getResponseHolder());
             }
         }
     }
-    
-    protected void render(ModelAndView mv, NestedServletRequest nestedRequest, NestedServletResponse nestedResponse) throws Exception {
+
+    protected void render(ModelAndView mv, PageFragmentRequest fragmentRequest, PageFragmentResponse fragmentResponse) throws Exception {
         if (!mv.isReference()) {
             setInternalResourceViewIncludeAlways(mv.getView());
         }
-        super.render(mv, nestedRequest, nestedResponse);
-    }
 
-    protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,
-            HttpServletRequest request) throws Exception {
-        View view = super.resolveViewName(viewName, model, locale, request);
-        if (isNestedHandlerMethodRendering(request)) {
-            setInternalResourceViewIncludeAlways(view);
-        }
-        return view;
+        PageFragmentConfig pfc = (PageFragmentConfig)mv.getModelMap().get(RouteMapping.PAGE_FRAGMENT_CONFIG);
+        PageFragmentContextImpl context = (PageFragmentContextImpl)fragmentRequest.getAttribute(RouteMapping.HANDLER_METHOD_CONTEXT);
+        context.setPageFragmentConfig(pfc);
+
+        super.render(mv, fragmentRequest, fragmentResponse);
     }
-    
+
     protected void setInternalResourceViewIncludeAlways(View view) {
         if (view != null && view instanceof InternalResourceView) {
             ((InternalResourceView)view).setAlwaysInclude(true); 

Copied: rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/support/PageFragmentRequest.java (from r1390464, rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/support/NestedServletRequest.java)
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/support/PageFragmentRequest.java?p2=rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/support/PageFragmentRequest.java&p1=rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/support/NestedServletRequest.java&r1=1390464&r2=1396567&rev=1396567&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/support/NestedServletRequest.java (original)
+++ rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/support/PageFragmentRequest.java Wed Oct 10 12:43:21 2012
@@ -37,10 +37,10 @@ import org.slf4j.LoggerFactory;
  *
  * @version "$Id$"
  */
-public class NestedServletRequest extends HttpServletRequestWrapper {
+public class PageFragmentRequest extends HttpServletRequestWrapper {
 
 
-    private static final Logger log = LoggerFactory.getLogger(NestedServletRequest.class);
+    private static final Logger log = LoggerFactory.getLogger(PageFragmentRequest.class);
     private String componentRequestUri;
     private boolean component;
     private Map<String, String> headers;
@@ -50,7 +50,7 @@ public class NestedServletRequest extend
      *
      * @throws IllegalArgumentException if the request is null
      */
-    public NestedServletRequest(HttpServletRequest request) {
+    public PageFragmentRequest(HttpServletRequest request) {
         super(request);
         headers = new HashMap<String, String>();
     }

Copied: rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/support/PageFragmentResponse.java (from r1390464, rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/support/NestedServletResponse.java)
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/support/PageFragmentResponse.java?p2=rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/support/PageFragmentResponse.java&p1=rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/support/NestedServletResponse.java&r1=1390464&r2=1396567&rev=1396567&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/support/NestedServletResponse.java (original)
+++ rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/support/PageFragmentResponse.java Wed Oct 10 12:43:21 2012
@@ -34,9 +34,9 @@ import org.slf4j.LoggerFactory;
 /**
  * @version "$Id$"
  */
-public class NestedServletResponse extends HttpServletResponseWrapper {
+public class PageFragmentResponse extends HttpServletResponseWrapper {
 
-    private static Logger log = LoggerFactory.getLogger(NestedServletResponse.class);
+    private static Logger log = LoggerFactory.getLogger(PageFragmentResponse.class);
 
     private final ResponseHolder responseHolder;
 
@@ -45,7 +45,7 @@ public class NestedServletResponse exten
      *
      * @throws IllegalArgumentException if the response is null
      */
-    public NestedServletResponse(HttpServletResponse response) {
+    public PageFragmentResponse(HttpServletResponse response) {
         super(response);
         responseHolder = new ResponseHolder(response);
     }

Modified: rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/support/ResponseHolder.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/support/ResponseHolder.java?rev=1396567&r1=1396566&r2=1396567&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/support/ResponseHolder.java (original)
+++ rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/support/ResponseHolder.java Wed Oct 10 12:43:21 2012
@@ -228,8 +228,8 @@ public class ResponseHolder {
     }
 
     public void forward(String pathInfo) throws IOException {
-        if (response instanceof NestedServletResponse) {
-            ((NestedServletResponse) response).forward(pathInfo);
+        if (response instanceof PageFragmentResponse) {
+            ((PageFragmentResponse) response).forward(pathInfo);
         }
         failIfCommitted();
         closed = true;
@@ -289,7 +289,7 @@ public class ResponseHolder {
      */
     public void setStatus(int statusCode) {
         if (!committed) {
-            if (response instanceof NestedServletResponse) {
+            if (response instanceof PageFragmentResponse) {
                 response.setStatus(statusCode);
             } else {
                 this.statusCode = statusCode;

Modified: rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/tags/IncludeComponentTag.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/tags/IncludeComponentTag.java?rev=1396567&r1=1396566&r2=1396567&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/tags/IncludeComponentTag.java (original)
+++ rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/tags/IncludeComponentTag.java Wed Oct 10 12:43:21 2012
@@ -26,8 +26,8 @@ import javax.servlet.jsp.JspException;
 import javax.servlet.jsp.JspWriter;
 import javax.servlet.jsp.tagext.TagSupport;
 
-import org.apache.rave.portal.web.mvc.RoutedHandlerMethod;
-import org.apache.rave.portal.web.mvc.support.NestedServletResponse;
+import org.apache.rave.portal.web.mvc.RouteMapping;
+import org.apache.rave.portal.web.mvc.support.PageFragmentResponse;
 import org.apache.rave.portal.web.mvc.support.ResponseHolder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -54,10 +54,10 @@ public class IncludeComponentTag extends
     public int doEndTag() throws JspException {
 
         @SuppressWarnings("unchecked")
-        Map<String, ResponseHolder> ccvrMap = (Map<String, ResponseHolder>) pageContext.getRequest().getAttribute(RoutedHandlerMethod.VIEW_RESPONSE_STATE);
+        Map<String, ResponseHolder> ccvrMap = (Map<String, ResponseHolder>) pageContext.getRequest().getAttribute(RouteMapping.VIEW_RESPONSE_STATE);
         if (ccvrMap != null && ccvrMap.containsKey(ref)) {
 
-            NestedServletResponse response = (NestedServletResponse) pageContext.getResponse();
+            PageFragmentResponse response = (PageFragmentResponse) pageContext.getResponse();
             if (response == null) {
                 if (log.isDebugEnabled()) {
                     log.error("Response was null");

Modified: rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/tags/PathTag.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/tags/PathTag.java?rev=1396567&r1=1396566&r2=1396567&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/tags/PathTag.java (original)
+++ rave/sandbox/content-services/rave-web-hmvc/src/main/java/org/apache/rave/portal/web/mvc/tags/PathTag.java Wed Oct 10 12:43:21 2012
@@ -20,18 +20,16 @@
 package org.apache.rave.portal.web.mvc.tags;
 
 import java.io.IOException;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import javax.servlet.jsp.JspException;
 import javax.servlet.jsp.PageContext;
 import javax.servlet.jsp.tagext.TagSupport;
 
 import org.apache.commons.lang.StringUtils;
-import org.apache.rave.portal.web.mvc.HandlerContext;
-import org.apache.rave.portal.web.mvc.RoutedHandlerMethod;
-import org.springframework.web.servlet.HandlerMapping;
+import org.apache.rave.portal.web.mvc.HandlerMethodContext;
+import org.apache.rave.portal.web.mvc.PageFragmentContext;
+import org.apache.rave.portal.web.mvc.RouteMapping;
+import org.apache.rave.portal.web.mvc.utils.PathUtils;
 
 public class PathTag extends TagSupport {
 
@@ -39,19 +37,15 @@ public class PathTag extends TagSupport 
 
     public static final String defaultUrlFor = "handler";
 
-    /** Captures URI template variable names.
-        Copied from org.springframework.web.util.UriComponents
-    */
-    private static final Pattern NAMES_PATTERN = Pattern.compile("\\{([^/]+?)\\}");
-
-    private String pathFor = null;
-    private String handler = null;
-
-
-    private String var;
-    private int scope = PageContext.PAGE_SCOPE;
+    private String route;
+    private String controller;
+    private String page;
+    private String fragmentPath;
+    private String handler;
     private boolean expandPathVariables = true;
+    private String var;
 
+    private int scope = PageContext.PAGE_SCOPE;
 
     @Override
     public int doStartTag() throws JspException {
@@ -61,69 +55,62 @@ public class PathTag extends TagSupport 
     @Override
     public int doEndTag() throws JspException {
 
-        HandlerContext context = (HandlerContext)pageContext.getRequest().getAttribute(RoutedHandlerMethod.HANDLER_CONTEXT);
+        HandlerMethodContext context = (HandlerMethodContext)pageContext.getRequest().getAttribute(RouteMapping.HANDLER_METHOD_CONTEXT);
         if (context != null) {
 
-            if (!StringUtils.isEmpty(handler)) {
+            String pathFor = "";
+
+            if (controller != null) {
+                context = context.getContextByRoute(controller, handler, route);
+                pathFor = handler != null ? "handler" : "route";
+            }
+            else if (page != null) {
+                context = context.getPageFragmentContextByRoute(page, fragmentPath, handler, route);
+                pathFor = handler != null ? "handler" : fragmentPath != null ? "fragment" : "route";
+            }
+            else if (route != null) {
+                context = context.getRouteContext(route);
+                pathFor = context != null && context.isPageFragmentContext() ? "route" : "handler";
+            }
+            else if (handler != null) {
                 context = context.getSiblingContext(handler);
+                pathFor = "handler";
             }
+            else {
+                context = null;
+            }
+
             if (context != null) {
-                if (StringUtils.isEmpty(pathFor) || defaultUrlFor.equalsIgnoreCase(pathFor)) {
+                String path = "";
+                if ("handler".equals(pathFor)) {
+                    path = context.getHandlerPath(expandPathVariables);
+                }
+                else if ("route".equals(pathFor)) {
+                    path = context.getRoutePath(expandPathVariables);
+                }
+                else if ("fragment".equals(pathFor)) {
+                    path = ((PageFragmentContext)context).getFragmentPath(expandPathVariables);
+                }
+                path = PathUtils.mergePaths(pageContext.getServletContext().getContextPath(), path);
 
-                    String path = context.getPath();
-                    if (expandPathVariables) {
-                        path = expandPath(path);
-                    }
-                    if (!StringUtils.isEmpty(var)) {
-                        pageContext.setAttribute(var, path, scope);
-                    }
-                    else {
-                        writeOutput(path);
-                    }
+                if (!StringUtils.isEmpty(var)) {
+                    pageContext.setAttribute(var, path, scope);
+                }
+                else {
+                    writeOutput(path);
                 }
             }
         }
-        pathFor = null;
+        controller = null;
+        page = null;
+        fragmentPath = null;
         handler = null;
+        route = null;
+        expandPathVariables = true;
         var = null;
         return EVAL_PAGE;
     }
 
-    /*
-     * Copied and adapted from org.springframework.web.util.UriComponents#expandUriComponent
-     */
-    private String expandPath(String path) {
-        if (path.indexOf('{') == -1) {
-            return path;
-        }
-        Map<String, String> variables =
-                (Map<String, String>) pageContext.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
-
-        if (variables == null || variables.isEmpty()) {
-            return path;
-        }
-
-        Matcher matcher = NAMES_PATTERN.matcher(path);
-        StringBuffer sb = new StringBuffer();
-        while (matcher.find()) {
-            String match = matcher.group(1);
-            String variableName = (match.indexOf(':') == -1) ? match : match.substring(0, match.indexOf(':'));
-            if (variables.containsKey(variableName)) {
-                String variableValue = variables.get(variableName);
-                if (variableValue == null) {
-                    variableValue = "";
-                }
-                String replacement = Matcher.quoteReplacement(variableValue);
-                matcher.appendReplacement(sb, replacement);
-            }
-            else {
-                matcher.appendReplacement(sb, matcher.group());
-            }
-        }
-        matcher.appendTail(sb);
-        return sb.toString();
-    }
-
     private void writeOutput(String str) throws JspException {
         try {
             pageContext.getOut().print(str);
@@ -132,14 +119,6 @@ public class PathTag extends TagSupport 
         }
     }
 
-    public String getPathFor() {
-        return pathFor;
-    }
-
-    public void setPathFor(String pathFor) {
-        this.pathFor = pathFor;
-    }
-
     public String getHandler() {
         return handler;
     }
@@ -148,6 +127,46 @@ public class PathTag extends TagSupport 
         this.handler = handler;
     }
 
+    public String getRoute() {
+        return route;
+    }
+
+    public void setRoute(final String route) {
+        this.route = route;
+    }
+
+    public String getPage() {
+        return page;
+    }
+
+    public void setPage(final String page) {
+        this.page = page;
+    }
+
+    public String getController() {
+        return controller;
+    }
+
+    public void setController(final String controller) {
+        this.controller = controller;
+    }
+
+    public String getFragmentPath() {
+        return fragmentPath;
+    }
+
+    public void setFragmentPath(final String fragmentPath) {
+        this.fragmentPath = fragmentPath;
+    }
+
+    public boolean isExpandPathVariables() {
+        return expandPathVariables;
+    }
+
+    public void setExpandPathVariables(final boolean expandPathVariables) {
+        this.expandPathVariables = expandPathVariables;
+    }
+
     public String getVar() {
         return var;
     }