Package org.ocpsoft.rewrite.faces

Source Code of org.ocpsoft.rewrite.faces.RewriteNavigationHandler

/*
* Copyright 2010 Lincoln Baxter, III
*
* Licensed 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.ocpsoft.rewrite.faces;

import java.io.IOException;
import java.util.Map;
import java.util.Set;

import javax.faces.application.ConfigurableNavigationHandler;
import javax.faces.application.NavigationCase;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;

import org.ocpsoft.rewrite.exception.RewriteException;
import org.ocpsoft.urlbuilder.AddressBuilder;

/**
* @author Lincoln Baxter, III <lincoln@ocpsoft.com>
*/
public class RewriteNavigationHandler extends ConfigurableNavigationHandler
{
   private static final String REWRITE_PREFIX = "rewrite:";
   public static final String REDIRECT_PREFIX = "rewrite-redirect:";
   private static final String IN_NAVIGATION = RewriteNavigationHandler.class.getName() + "_inNavigation";
   private final ConfigurableNavigationHandler parent;

   public RewriteNavigationHandler(final ConfigurableNavigationHandler parent)
   {
      this.parent = parent;
   }

   @Override
   public void handleNavigation(final FacesContext context, final String fromAction, final String outcome)
   {
      if (!redirect(context, outcome))
      {
         setInNavigation((HttpServletRequest) context.getExternalContext().getRequest(), true);

         /*
          * the view root may be null if the navigation occurs before RESTORE_VIEW
          *
          * https://github.com/ocpsoft/rewrite/issues/142
          */
         String originalViewId = null;
         if(context.getViewRoot() != null)
         {
           originalViewId = context.getViewRoot().getViewId();
         }
        
         parent.handleNavigation(context, fromAction, outcome);

         /*
          * the view root may be null as a result of a ViewExpiredException
          *
          * https://github.com/ocpsoft/rewrite/issues/103
          */
         String newViewId = null;
         if (context.getViewRoot() != null)
         {
            newViewId = context.getViewRoot().getViewId();
         }

        
         /*
          * Navigation is complete if the viewId has not changed or the response is complete
          */
         if ((true == context.getResponseComplete()) || (originalViewId == newViewId) || (originalViewId != null && originalViewId.equals(newViewId)))
         {
            setInNavigation((HttpServletRequest) context.getExternalContext().getRequest(), false);
         }
      }
   }

   private void setInNavigation(final HttpServletRequest request, final boolean inNavigation)
   {
      request.setAttribute(IN_NAVIGATION, inNavigation);
   }

   public static boolean isInNavigation(final HttpServletRequest request)
   {
      Boolean inNavigation = (Boolean) request.getAttribute(IN_NAVIGATION);
      return inNavigation == null ? false : inNavigation;
   }

   @Override
   public NavigationCase getNavigationCase(final FacesContext context, final String fromAction, final String outcome)
   {
      // TODO integrate rewrite with navigation (See PrettyNavigationHandler)
      if (REWRITE_PREFIX.equals(outcome))
      {
         String viewId = context.getViewRoot().getViewId();
         NavigationCase navigationCase = parent.getNavigationCase(context, fromAction, viewId);
         return navigationCase;
      }
      else if (outcome != null && outcome.startsWith(REDIRECT_PREFIX)) {
         String url = outcome.substring(REDIRECT_PREFIX.length());
         String viewId = AddressBuilder.create(url).getPath();
         return parent.getNavigationCase(context, fromAction, viewId);
      }
      else
      {
         NavigationCase navigationCase = parent.getNavigationCase(context, fromAction, outcome);
         return navigationCase;
      }
   }

   private boolean redirect(final FacesContext context, final String outcome)
   {
      ExternalContext externalContext = context.getExternalContext();

      if (REWRITE_PREFIX.equals(outcome))
      {
         String target = FacesRewriteLifecycleListener.getOriginalRequestURL((HttpServletRequest) externalContext
                  .getRequest());
         String redirectUrl = externalContext.encodeRedirectURL(target, null);
         try {
            externalContext.redirect(redirectUrl);
            return true;
         }
         catch (IOException e) {
            throw new RewriteException("Could not redirect to [" + redirectUrl + "]", e);
         }
      }

      // outcomes created by Navigate for redirects
      else if (outcome != null && outcome.startsWith(REDIRECT_PREFIX)) {

         // strip the prefix to get the context-relative URL
         String relativeUrl = outcome.substring(REDIRECT_PREFIX.length());

         // add the context path
         String absoluteUrl = prependContextPath(externalContext, relativeUrl);

         // rewrite the URL
         String rewrittenUrl = externalContext.encodeActionURL(absoluteUrl);

         // send the redirect
         try {
            externalContext.redirect(rewrittenUrl);
            return true;
         }
         catch (IOException e) {
            throw new RewriteException("Could not redirect to [" + rewrittenUrl + "]", e);
         }

      }

      return false;
   }

   /**
    * Adds the context path to the given context-relative URL.
    */
   private String prependContextPath(ExternalContext externalContext, String url)
   {
      String contextPath = externalContext.getRequestContextPath();
      if ("/".equals(contextPath) || (url.startsWith(contextPath))) {
         return url;
      }
      return contextPath + url;
   }

   @Override
   public Map<String, Set<NavigationCase>> getNavigationCases()
   {
      return parent.getNavigationCases();
   }

   @Override
   public void performNavigation(final String outcome)
   {
      parent.performNavigation(outcome);
   }
}
TOP

Related Classes of org.ocpsoft.rewrite.faces.RewriteNavigationHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.